n*****t 发帖数: 22014 | 1 有 mongodb collection 如下:{ id, parent },现需将这个 array 变成 tree。表
比较大,读到内存再遍历太费内存、太慢,请大牛看看 async 怎么做。
500 伪币酬谢。 |
p*****2 发帖数: 21240 | 2 没看明白。你这个在mongo中已经形成了一个tree了呀。你想做什么query呀。 |
i**i 发帖数: 1500 | 3 哥,不能比这更简单了吧?
啥叫树? 就是 {id, [child,...]}, 对吧?
你知道了吧。 |
i**i 发帖数: 1500 | |
n*****t 发帖数: 22014 | 5 不是,mongo 里存的是 array
{ id: '子1', parent: '老王' }
{ id: '子2', parent: '老王' }
{ id: '孙1', parent: '子1' }
{ id: '孙2', parent: '子1' }
{ id: '孙3', parent: '子2' }
需要变成:
老王 : [
子1 : [ 孙1, 孙2 ],
子2 : [ 孙3 ]
]
【在 p*****2 的大作中提到】 : 没看明白。你这个在mongo中已经形成了一个tree了呀。你想做什么query呀。
|
n*****t 发帖数: 22014 | 6 书少别骗,请给出 async
【在 i**i 的大作中提到】 : 哥,不能比这更简单了吧? : 啥叫树? 就是 {id, [child,...]}, 对吧? : 你知道了吧。
|
i**i 发帖数: 1500 | 7 不给就算了。
【在 n*****t 的大作中提到】 : 不是,mongo 里存的是 array : { id: '子1', parent: '老王' } : { id: '子2', parent: '老王' } : { id: '孙1', parent: '子1' } : { id: '孙2', parent: '子1' } : { id: '孙3', parent: '子2' } : 需要变成: : 老王 : [ : 子1 : [ 孙1, 孙2 ], : 子2 : [ 孙3 ]
|
p*****2 发帖数: 21240 | 8 最后的tree存在mongo里 还是memory里
collection有多少records
【在 n*****t 的大作中提到】 : 不是,mongo 里存的是 array : { id: '子1', parent: '老王' } : { id: '子2', parent: '老王' } : { id: '孙1', parent: '子1' } : { id: '孙2', parent: '子1' } : { id: '孙3', parent: '子2' } : 需要变成: : 老王 : [ : 子1 : [ 孙1, 孙2 ], : 子2 : [ 孙3 ]
|
n*****t 发帖数: 22014 | 9 存在 memory 里,records 现在有 1W 多吧,db find 肯定比在 memory 里快,因为可
以用到 index。其实问题找到了,肯定是 async 递归,忘记 find 结果要 copy 一下。
【在 p*****2 的大作中提到】 : 最后的tree存在mongo里 还是memory里 : collection有多少records
|
p*****2 发帖数: 21240 | 10 那就好 这个问题也是常见
下。
【在 n*****t 的大作中提到】 : 存在 memory 里,records 现在有 1W 多吧,db find 肯定比在 memory 里快,因为可 : 以用到 index。其实问题找到了,肯定是 async 递归,忘记 find 结果要 copy 一下。
|
|
|
c******y 发帖数: 29 | 11 不了解mongodb,oracle的话就是用connected by(不加order by),结果本身顺序就
是按照depth first顺序展开的,遍历一边就行
【在 n*****t 的大作中提到】 : 有 mongodb collection 如下:{ id, parent },现需将这个 array 变成 tree。表 : 比较大,读到内存再遍历太费内存、太慢,请大牛看看 async 怎么做。 : 500 伪币酬谢。
|
W***o 发帖数: 6519 | 12 以前写过一个类似的,就是先找儿子,再给每个儿子找儿子:
var async = require('async');
var parentLaoWang = "Lao Wang"
if (parentLaoWang) {
var laoWangFamily = {"laoWang": []};
var findKidByParent = function(parent, callback) {
//findKidsByParent is a custom function on Kids collection
Kids.findKidsByParent(parent, function (err, foundKids) {
//foundKids is Array
if (foundKids) {
var currParentAndKids = {"parent" : parent, "kids" :
foundKids};
laoWangFamily.laoWang.push(currParentAndKids);
}
callback();
});
}; //findKidByParent
var retKids = function(err) {
if (err) return sendErrorMsgCode(res, "error in assembling kids",
401);
return laoWangFamily;
}; //retTagNames
// 先找儿子辈
var laoWangsSons = [];
Kids.findKidsByParent(parentLaoWang, function(error, foundSons) {
laoWangsSons = foundSons;
//再给每个儿子找儿子辈的
async.eachSeries(laoWangsSons, findKidByParent, retKids);
});
}
【在 n*****t 的大作中提到】 : 有 mongodb collection 如下:{ id, parent },现需将这个 array 变成 tree。表 : 比较大,读到内存再遍历太费内存、太慢,请大牛看看 async 怎么做。 : 500 伪币酬谢。
|
l**********n 发帖数: 8443 | 13 这个非常简单。本质就是一async recursive query, 你可以用while loop, 也可以写
成递归。递归的话注意pass中间结果。我用bluebird写过。promise用过吧,当你得到
想要的结果,call resolve退出循环或递归
【在 n*****t 的大作中提到】 : 有 mongodb collection 如下:{ id, parent },现需将这个 array 变成 tree。表 : 比较大,读到内存再遍历太费内存、太慢,请大牛看看 async 怎么做。 : 500 伪币酬谢。
|
l**********n 发帖数: 8443 | 14 google 'while loop with promise' at stackoverflow
【在 l**********n 的大作中提到】 : 这个非常简单。本质就是一async recursive query, 你可以用while loop, 也可以写 : 成递归。递归的话注意pass中间结果。我用bluebird写过。promise用过吧,当你得到 : 想要的结果,call resolve退出循环或递归
|
n*****t 发帖数: 22014 | 15 谢 code,这一行有问题的吧:
var currParentAndKids = {"parent" : parent, "kids" : foundKids};
foundKids 要 copy 一下,之前我就是忘记了。
【在 W***o 的大作中提到】 : 以前写过一个类似的,就是先找儿子,再给每个儿子找儿子: : var async = require('async'); : var parentLaoWang = "Lao Wang" : if (parentLaoWang) { : var laoWangFamily = {"laoWang": []}; : var findKidByParent = function(parent, callback) { : //findKidsByParent is a custom function on Kids collection : Kids.findKidsByParent(parent, function (err, foundKids) { : //foundKids is Array : if (foundKids) {
|
n*****t 发帖数: 22014 | 16 一开始我是读到 memory 里再便历,比较耗资源、比较慢。然后递归查询,速度还好,
因为 find 可以用到 index。
现在想有没有更好的算法。
【在 l**********n 的大作中提到】 : 这个非常简单。本质就是一async recursive query, 你可以用while loop, 也可以写 : 成递归。递归的话注意pass中间结果。我用bluebird写过。promise用过吧,当你得到 : 想要的结果,call resolve退出循环或递归
|
p***o 发帖数: 1252 | 17 你不是才1万多records吗?为啥读到memory里比较耗资源?
【在 n*****t 的大作中提到】 : 一开始我是读到 memory 里再便历,比较耗资源、比较慢。然后递归查询,速度还好, : 因为 find 可以用到 index。 : 现在想有没有更好的算法。
|
W***o 发帖数: 6519 | 18 我没有跑,只是早上改写了一下,mongodb 的find 是async 的,相当于promise, 只是
用async library 同时跑很多
【在 n*****t 的大作中提到】 : 谢 code,这一行有问题的吧: : var currParentAndKids = {"parent" : parent, "kids" : foundKids}; : foundKids 要 copy 一下,之前我就是忘记了。 :
|
n*****t 发帖数: 22014 | 19 贴一下最终实现
// model is the mongoose collection Model
function getTree(parent_cid, cb) {
var node = {};
model.find({
parent_cid : parent_cid || 0,
}).exec(function(err, results) {
if (err)
return cb(err);
async.each(results, function(x, next) {
getTree(x.cid, function(err, nodes) {
node[x.name] = nodes;
next(err);
});
}, function(err) {
cb(err, node);
});
});
} |
m******u 发帖数: 12400 | |
|
|
i**i 发帖数: 1500 | 21 1 没必要用啥库了。
2 要判断tree遍历结束。
随便写了一个:
var treeBuilder = (function () {
var count = 0;
var tree = {};
return {
setRoot: function (root) {
tree[root] = {};
this.grow(tree[root], root);
return this;
},
onDone: function (cb) {
this._cb = cb;
return this;
},
grow: function (root, branch) {
console.log("add: " + branch);
var self = this;
count++;
findChildren(branch, function (children) {
children.forEach(function (c) {
root[c] = {};
self.grow(root[c], c);
});
count--;
if (count == 0) {
self._cb(tree);
}
});
}
};
})();
treeBuilder
.onDone(function (tree) {
console.dir(tree);
})
.setRoot(1);
【在 n*****t 的大作中提到】 : 贴一下最终实现 : // model is the mongoose collection Model : function getTree(parent_cid, cb) { : var node = {}; : model.find({ : parent_cid : parent_cid || 0, : }).exec(function(err, results) { : if (err) : return cb(err); : async.each(results, function(x, next) {
|
d******e 发帖数: 2265 | 22 你这设计就有问题
直接存成下面的什么都不用高了
你的设计还是SQL de关系
【在 n*****t 的大作中提到】 : 不是,mongo 里存的是 array : { id: '子1', parent: '老王' } : { id: '子2', parent: '老王' } : { id: '孙1', parent: '子1' } : { id: '孙2', parent: '子1' } : { id: '孙3', parent: '子2' } : 需要变成: : 老王 : [ : 子1 : [ 孙1, 孙2 ], : 子2 : [ 孙3 ]
|
n*****t 发帖数: 22014 | 23 async 更简洁吧,另外 findChildren 返回空就是结束了,不需要 count
【在 i**i 的大作中提到】 : 1 没必要用啥库了。 : 2 要判断tree遍历结束。 : 随便写了一个: : var treeBuilder = (function () { : var count = 0; : var tree = {}; : return { : setRoot: function (root) { : tree[root] = {}; : this.grow(tree[root], root);
|
n*****t 发帖数: 22014 | 24 两码事好伐,树生成一次就可以了,还有其他操作。举个例子,给出 id 需要取出
name,当然是 indexed array 比你便历数快多了。
马工不能自己图方便就让客户改需求。
【在 d******e 的大作中提到】 : 你这设计就有问题 : 直接存成下面的什么都不用高了 : 你的设计还是SQL de关系
|
i**i 发帖数: 1500 | 25 async去掉以后更简洁。findChildren是一个小twig结束了。你怎知隔壁老王有没有结
束?
需要判断整体结束。
老哥的基本功不咋地呀。
【在 n*****t 的大作中提到】 : async 更简洁吧,另外 findChildren 返回空就是结束了,不需要 count
|
n*****t 发帖数: 22014 | 26 我的代码是你的一半吧,而且你的 find 都没实际实现,err 也没处理。
隔壁老王结束没结束跟我啥关系啊?把 found 加到 children 里就行了啊,每个
found 都结束了就是 done,最后递归 callback。
感觉你是没理解 async 吧。
【在 i**i 的大作中提到】 : async去掉以后更简洁。findChildren是一个小twig结束了。你怎知隔壁老王有没有结 : 束? : 需要判断整体结束。 : 老哥的基本功不咋地呀。
|
i**i 发帖数: 1500 | 27 你牛,你随意。
对了。理解好了以后,再上来吱一声。谢谢。
【在 n*****t 的大作中提到】 : 我的代码是你的一半吧,而且你的 find 都没实际实现,err 也没处理。 : 隔壁老王结束没结束跟我啥关系啊?把 found 加到 children 里就行了啊,每个 : found 都结束了就是 done,最后递归 callback。 : 感觉你是没理解 async 吧。
|
n*****t 发帖数: 22014 | 28 分特,本质是个递归,只不过用 async 写,你告诉我为什么要知道隔壁老王结束没结
束。
【在 i**i 的大作中提到】 : 你牛,你随意。 : 对了。理解好了以后,再上来吱一声。谢谢。
|
i**i 发帖数: 1500 | 29 "你告诉我为什么要知道隔壁老王结束没结束。"
假定树是
1
/
2 3
| |
4 5
findChildren( ,2) 发出后2秒返回结果。
findChildren( ,3) 发出后3秒返回结果。
findChildren( ,2)结束后,需要不需要知道隔壁老王结束没有啊?
【在 n*****t 的大作中提到】 : 分特,本质是个递归,只不过用 async 写,你告诉我为什么要知道隔壁老王结束没结 : 束。
|
n*****t 发帖数: 22014 | 30 所以我说你大概没理解 async,用法是这样的:
each(array, forEachChild, allDone)
这个库本身已经 take care 老王了,只有所有老王的儿子都找到了,才会执行
allDone
【在 i**i 的大作中提到】 : "你告诉我为什么要知道隔壁老王结束没结束。" : 假定树是 : 1 : / : 2 3 : | | : 4 5 : findChildren( ,2) 发出后2秒返回结果。 : findChildren( ,3) 发出后3秒返回结果。 : findChildren( ,2)结束后,需要不需要知道隔壁老王结束没有啊?
|
|
|
i**i 发帖数: 1500 | 31 不想讨论了。到此为止吧。
【在 n*****t 的大作中提到】 : 所以我说你大概没理解 async,用法是这样的: : each(array, forEachChild, allDone) : 这个库本身已经 take care 老王了,只有所有老王的儿子都找到了,才会执行 : allDone
|
n*****t 发帖数: 22014 | 32 你这个 counter 写得也有问题,假如老王只有 2 个儿子,grow 3 次,你自己心算一下
【在 i**i 的大作中提到】 : 不想讨论了。到此为止吧。
|
c*********e 发帖数: 16335 | 33 同意。
【在 n*****t 的大作中提到】 : 所以我说你大概没理解 async,用法是这样的: : each(array, forEachChild, allDone) : 这个库本身已经 take care 老王了,只有所有老王的儿子都找到了,才会执行 : allDone
|
c*********e 发帖数: 16335 | 34 3个问题
1。 getTree function的 callback function cb怎么写的?
2。 nodes从哪来的,怎么赋值的?你的gettree() function里面并没有写nodes怎么赋
值啊。
3。 next(err);是async.each item执行后的call back,应该只需要call一次。你如果
放到递归recursion里,最后递归退出是通过
if (err)
return cb(err);
那 next(err)就没有被call到。
async.each(results, function(x, next) {
getTree(x.cid, function(err, nodes) {
node[x.name] = nodes;
next(err); //next(err);放这对吗?
});
//next(err); 要移到这吗?
}, function(err) {
cb(err, node);
})
// model is the mongoose collection Model
function getTree(parent_cid, cb) {
var node = {};
model.find({
parent_cid : parent_cid || 0,
}).exec(function(err, results) {
if (err)
return cb(err);
async.each(results, function(x, next) {
getTree(x.cid, function(err, nodes) {
node[x.name] = nodes;
next(err);
});
}, function(err) {
cb(err, node);
}); //end of async each
}); //end of exec
}
【在 n*****t 的大作中提到】 : 贴一下最终实现 : // model is the mongoose collection Model : function getTree(parent_cid, cb) { : var node = {}; : model.find({ : parent_cid : parent_cid || 0, : }).exec(function(err, results) { : if (err) : return cb(err); : async.each(results, function(x, next) {
|
i**i 发帖数: 1500 | 35 又读了一下你的代码,发现你的实现是对的。
我不用async。
【在 n*****t 的大作中提到】 : 所以我说你大概没理解 async,用法是这样的: : each(array, forEachChild, allDone) : 这个库本身已经 take care 老王了,只有所有老王的儿子都找到了,才会执行 : allDone
|
d******e 发帖数: 2265 | 36 nosql不是这么玩的。
都是按照query来设计数据存储。如果你需要查id,在id上见index好了。
child 就放到sub-doc。数据冗余一些没关系
不过既然是客户这么设计的,那么你只好写query了。
【在 n*****t 的大作中提到】 : 两码事好伐,树生成一次就可以了,还有其他操作。举个例子,给出 id 需要取出 : name,当然是 indexed array 比你便历数快多了。 : 马工不能自己图方便就让客户改需求。
|
n*****t 发帖数: 22014 | 37 设想一个 category tree,一方面我要构建 menu,另一方面给出 category id 迅速找
到 name,是把 sub category 放在 root 的 suc-doc 方便还是做成 array?
【在 d******e 的大作中提到】 : nosql不是这么玩的。 : 都是按照query来设计数据存储。如果你需要查id,在id上见index好了。 : child 就放到sub-doc。数据冗余一些没关系 : 不过既然是客户这么设计的,那么你只好写query了。
|
n*****t 发帖数: 22014 | 38 1) function(err, node)
2) node 就是 getTree callback 得到的 sub tree
3) cb 有 2 个地方会 call,一个是 err,一个是 getTree 得到结果了
next 移到后面,get sub tree 没得到结果就返回了,肯定不对
【在 c*********e 的大作中提到】 : 3个问题 : 1。 getTree function的 callback function cb怎么写的? : 2。 nodes从哪来的,怎么赋值的?你的gettree() function里面并没有写nodes怎么赋 : 值啊。 : 3。 next(err);是async.each item执行后的call back,应该只需要call一次。你如果 : 放到递归recursion里,最后递归退出是通过 : if (err) : return cb(err); : 那 next(err)就没有被call到。 : async.each(results, function(x, next) {
|
l**********n 发帖数: 8443 | 39 array. you can load all menu items into memory, and then build the tree in
memory.
【在 n*****t 的大作中提到】 : 设想一个 category tree,一方面我要构建 menu,另一方面给出 category id 迅速找 : 到 name,是把 sub category 放在 root 的 suc-doc 方便还是做成 array?
|
n*****t 发帖数: 22014 | 40 现在就是这样实现,npm start 的时候 build tree,存到 json,ajax 到 client 由
angular render 成 menu
【在 l**********n 的大作中提到】 : array. you can load all menu items into memory, and then build the tree in : memory.
|
|
|
z****e 发帖数: 54598 | 41 老姜,这种一般都直接写成properties
而非存到persistance里面去
xml用得比较多,多弄点app就知道了,基本上都是xml在搞
android,fxml,就只有ios是json
当然其他语言parse xml很弱,你做成json也是一种方式
但是基本都是properties,比较少做成persistance
还有就是,即便你要这样搞,这种接近metdata的数据
也是用db比较多,你用nosql算是各种奇芭
由
【在 n*****t 的大作中提到】 : 现在就是这样实现,npm start 的时候 build tree,存到 json,ajax 到 client 由 : angular render 成 menu
|
l**********n 发帖数: 8443 | 42 yaml
【在 z****e 的大作中提到】 : 老姜,这种一般都直接写成properties : 而非存到persistance里面去 : xml用得比较多,多弄点app就知道了,基本上都是xml在搞 : android,fxml,就只有ios是json : 当然其他语言parse xml很弱,你做成json也是一种方式 : 但是基本都是properties,比较少做成persistance : 还有就是,即便你要这样搞,这种接近metdata的数据 : 也是用db比较多,你用nosql算是各种奇芭 : : 由
|
n*****t 发帖数: 22014 | 43 赵老师你也是一桶浆糊,前面不说了,每个 node 下面还有一堆 sub-doc,你不问需求
就在这夸夸其谈。还有,即使 db 和 nosql 都可以,选择 nosql 了怎么就各种奇葩,
您说来听听?
【在 z****e 的大作中提到】 : 老姜,这种一般都直接写成properties : 而非存到persistance里面去 : xml用得比较多,多弄点app就知道了,基本上都是xml在搞 : android,fxml,就只有ios是json : 当然其他语言parse xml很弱,你做成json也是一种方式 : 但是基本都是properties,比较少做成persistance : 还有就是,即便你要这样搞,这种接近metdata的数据 : 也是用db比较多,你用nosql算是各种奇芭 : : 由
|
d******e 发帖数: 2265 | 44 要是我就考虑顶层category写成一个json.下面的都是它的sub-doc
sub category存成.
{_id:id, path: “top/child/child-2/child3}
要是找sub-doc就用json path.
【在 n*****t 的大作中提到】 : 设想一个 category tree,一方面我要构建 menu,另一方面给出 category id 迅速找 : 到 name,是把 sub category 放在 root 的 suc-doc 方便还是做成 array?
|
a9 发帖数: 21638 | 45 你要找一个child(x) where name='老三'的话,你这个存法可是要难受死了
速找
【在 d******e 的大作中提到】 : 要是我就考虑顶层category写成一个json.下面的都是它的sub-doc : sub category存成. : {_id:id, path: “top/child/child-2/child3} : 要是找sub-doc就用json path.
|
d******e 发帖数: 2265 | 46 那每个doc加上一个name,然后index一下好了。总之,围绕query设计schema.
其实如果只有1万的量,要我就直接都读进来,然后flatten.filter(_.name ="老三“)
【在 a9 的大作中提到】 : 你要找一个child(x) where name='老三'的话,你这个存法可是要难受死了 : : 速找
|
n*****t 发帖数: 22014 | 47 围绕 query 设计就是 array,树是准静态,find by name or id 频繁操作。
你的设计只有一棵大树,加 index 没用了。
【在 d******e 的大作中提到】 : 那每个doc加上一个name,然后index一下好了。总之,围绕query设计schema. : 其实如果只有1万的量,要我就直接都读进来,然后flatten.filter(_.name ="老三“)
|
c*********e 发帖数: 16335 | 48 你这个function的结果,node["老王"] 里面只会包含一个儿子: “子一”或者“子二
”,不可能同时包含2个或者多个儿子。
你运行了这个function吗?结果正确吗?
// model is the mongoose collection Model
function getTree(parent_cid, cb) {
var node = {};
model.find({
parent_cid : parent_cid || 0,
}).exec(function(err, results) {
if (err)
return cb(err);
async.each(results, function(x, next) {
getTree(x.cid, function(err, nodes) {
node[x.name] = nodes;
next(err);
});
}, function(err) {
cb(err, node);
}); //end of async each
}); //end of exec
}
【在 n*****t 的大作中提到】 : 1) function(err, node) : 2) node 就是 getTree callback 得到的 sub tree : 3) cb 有 2 个地方会 call,一个是 err,一个是 getTree 得到结果了 : next 移到后面,get sub tree 没得到结果就返回了,肯定不对
|
n*****t 发帖数: 22014 | 49 当然运行了,肯定正常。
你还是没理解 async,next 要在对当前 element 操作结束后再 call,也就是要等异
步的结果出来。所有 next 都结束后才能去执行 done。
【在 c*********e 的大作中提到】 : 你这个function的结果,node["老王"] 里面只会包含一个儿子: “子一”或者“子二 : ”,不可能同时包含2个或者多个儿子。 : 你运行了这个function吗?结果正确吗? : : // model is the mongoose collection Model : function getTree(parent_cid, cb) { : var node = {}; : model.find({ : parent_cid : parent_cid || 0, : }).exec(function(err, results) {
|
c*********e 发帖数: 16335 | 50 看不懂你的逻辑,call function的时候的参数是什么,能给个例子吗?
结果正常就好。
【在 n*****t 的大作中提到】 : 当然运行了,肯定正常。 : 你还是没理解 async,next 要在对当前 element 操作结束后再 call,也就是要等异 : 步的结果出来。所有 next 都结束后才能去执行 done。
|
|
|
n*****t 发帖数: 22014 | 51 next 只有一个参数 err,就是告诉 async 子任务完成,有没有出错。
这么解释吧,一个组 20 个人分段挖路,每个人完成之后向组长报告。如果有人说我这
段挖不了有煤气管,组长就通知老板没法干活、咱收工了。如果所有人都报告完工,组
长给老板打电话、收队换下一波。
所以,任务分配之后,每个人要完成任务之后再向组长汇报,而不是刚接到任务就报告。
【在 c*********e 的大作中提到】 : 看不懂你的逻辑,call function的时候的参数是什么,能给个例子吗? : 结果正常就好。
|
c*********e 发帖数: 16335 | 52 next(err);其实也可以写成next();
你想async.each里每个item都执行,对吧,那这个next();和next(err);最后执行的结
果是一样的。如果each里有一个出错,就马上停止了,然后执行async.each的callback.
所以,next();其实就是放个空炮,不起任何实际作用。
告。
【在 n*****t 的大作中提到】 : next 只有一个参数 err,就是告诉 async 子任务完成,有没有出错。 : 这么解释吧,一个组 20 个人分段挖路,每个人完成之后向组长报告。如果有人说我这 : 段挖不了有煤气管,组长就通知老板没法干活、咱收工了。如果所有人都报告完工,组 : 长给老板打电话、收队换下一波。 : 所以,任务分配之后,每个人要完成任务之后再向组长汇报,而不是刚接到任务就报告。
|
n*****t 发帖数: 22014 | 53 啥?当然不一样,next 不报错,最后 cb 就以为都成功了。就好比挖坑的必须告诉组
长结果如何,不能简单说我走了。
callback.
【在 c*********e 的大作中提到】 : next(err);其实也可以写成next(); : 你想async.each里每个item都执行,对吧,那这个next();和next(err);最后执行的结 : 果是一样的。如果each里有一个出错,就马上停止了,然后执行async.each的callback. : 所以,next();其实就是放个空炮,不起任何实际作用。 : : 告。
|
c******y 发帖数: 29 | 54 mongo的recursive/connect by query能不能返回这种顺序的结果,本身就是depth
first search顺序的而且带level和leaf,生成树非常方便啊,oracle下做过
{ id: '老王', parent: null, level: 0, leaf: false }
{ id: '子1', parent: '老王', level: 1, leaf: false }
{ id: '孙1', parent: '子1', level: 2, leaf: true }
{ id: '孙2', parent: '子1', level: 2, leaf: true }
{ id: '子2', parent: '老王', level: 1, leaf: false }
{ id: '孙3', parent: '子2', level: 2, leaf: true}
【在 n*****t 的大作中提到】 : 不是,mongo 里存的是 array : { id: '子1', parent: '老王' } : { id: '子2', parent: '老王' } : { id: '孙1', parent: '子1' } : { id: '孙2', parent: '子1' } : { id: '孙3', parent: '子2' } : 需要变成: : 老王 : [ : 子1 : [ 孙1, 孙2 ], : 子2 : [ 孙3 ]
|
n*****t 发帖数: 22014 | 55 有意思,回头研究一下。不过感觉效率是一样的吧,mango 做还是 app 做的区别,
query 之后还要手工拼。
【在 c******y 的大作中提到】 : mongo的recursive/connect by query能不能返回这种顺序的结果,本身就是depth : first search顺序的而且带level和leaf,生成树非常方便啊,oracle下做过 : { id: '老王', parent: null, level: 0, leaf: false } : { id: '子1', parent: '老王', level: 1, leaf: false } : { id: '孙1', parent: '子1', level: 2, leaf: true } : { id: '孙2', parent: '子1', level: 2, leaf: true } : { id: '子2', parent: '老王', level: 1, leaf: false } : { id: '孙3', parent: '子2', level: 2, leaf: true}
|
n*****t 发帖数: 22014 | 56 mongo 好像不支持这样的 query,关于 tree 的存储,他们是这样说的:
http://docs.mongodb.org/manual/tutorial/model-tree-structures/
基本上还是 array 存储 linked list
【在 c******y 的大作中提到】 : mongo的recursive/connect by query能不能返回这种顺序的结果,本身就是depth : first search顺序的而且带level和leaf,生成树非常方便啊,oracle下做过 : { id: '老王', parent: null, level: 0, leaf: false } : { id: '子1', parent: '老王', level: 1, leaf: false } : { id: '孙1', parent: '子1', level: 2, leaf: true } : { id: '孙2', parent: '子1', level: 2, leaf: true } : { id: '子2', parent: '老王', level: 1, leaf: false } : { id: '孙3', parent: '子2', level: 2, leaf: true}
|
c*********e 发帖数: 16335 | 57 next一旦报错,整个async.each(){}就马上中止,然后就callback了。你难道不想把
results的每一个成员都处理一次?
【在 n*****t 的大作中提到】 : 啥?当然不一样,next 不报错,最后 cb 就以为都成功了。就好比挖坑的必须告诉组 : 长结果如何,不能简单说我走了。 : : callback.
|
n*****t 发帖数: 22014 | 58 如果需要这样,next 不要传递 err,每个 element 的结果存到一个 array
【在 c*********e 的大作中提到】 : next一旦报错,整个async.each(){}就马上中止,然后就callback了。你难道不想把 : results的每一个成员都处理一次?
|
c*********e 发帖数: 16335 | 59 对。
async的每个分支之间互相交流的方法有限,这方面还是multi-threading做得深入些。
【在 n*****t 的大作中提到】 : 如果需要这样,next 不要传递 err,每个 element 的结果存到一个 array
|