Javascript 多个查询以不可预测的排序结果结束
我的数据库中有几百个文档。模式非常简单:Javascript 多个查询以不可预测的排序结果结束,javascript,node.js,mongodb,express,mongoose,Javascript,Node.js,Mongodb,Express,Mongoose,我的数据库中有几百个文档。模式非常简单: var firmsSchema = mongoose.Schema({ name: String, sections: [String], }); 我想查询文档并遍历: {{#each sections}} {{sectionName}} {{#each firms}} {{firmName}} {{/each}} {{/each}} 简单: const SECTIONS = ['name_one', 'name_two'
var firmsSchema = mongoose.Schema({
name: String,
sections: [String],
});
我想查询文档并遍历:
{{#each sections}}
{{sectionName}}
{{#each firms}}
{{firmName}}
{{/each}}
{{/each}}
简单:
const SECTIONS = ['name_one', 'name_two', 'name_three'];
const UNSORTED_SECTION_NAME = 'unsorted';
router.get('/', function(req, res, next) {
var showFirms = function showSection (i, acc) {
if (i < 0) return;
let query = SECTIONS[i] ? {sections: SECTIONS[i]} : {sections: {$nin: SECTIONS}};
let key = SECTIONS[i] || UNSORTED_SECTION_NAME;
Firms.find(query).
then((result) => {
acc.push({
section: key,
firms: result,
});
if (i === SECTIONS.length) {
acc = acc.sort((a, b) => (a.section > b.section));
res.render('template', {
sections: acc,
});
}
}).
then(showSection (i - 1, acc));
}
showFirms(SECTIONS.length, []);
};
const SECTIONS=['name_one'、'name_two'、'name_two'、'name_two';
const UNSORTED_SECTION_NAME='UNSORTED';
router.get('/',函数(req,res,next){
var显示公司=功能显示部分(i,acc){
如果(i<0)返回;
让query=SECTIONS[i]?{SECTIONS:SECTIONS[i]}:{SECTIONS:{$nin:SECTIONS}};
让key=SECTIONS[i]| | UNSORTED_SECTION_NAME;
查找(查询)。
然后((结果)=>{
加速推({
第节:关键,
公司:结果,
});
如果(i==节.长度){
acc=acc.sort((a,b)=>(a.段>b.段));
res.render('模板'{
章节:行政协调会,
});
}
}).
然后(显示部分(i-1,acc));
}
展示公司(章节长度,[]);
};
工作正常。除了返回随机且不可预测排序的acc
之外。我的意思是'name\u-two'
部分可以跟在'name\u-one'
后面,反之亦然
我原以为在承诺链末尾的.sort()
可以解决所有异步问题,但事实并非如此
当然,在我将Handlebar helper传递到模板后,我可以使用Handlebar helper对acc
进行排序,但奇怪的是,在我的Show Companys
函数中完成所有查询后,我无法对其进行排序
你能给我一些建议吗?看看这段代码的重拍。我们不是一个接一个地获取数据,而是在同一时间(异步)获取数据,然后处理返回 如果你有任何问题,我在这里,这个代码是未经测试,所以给我一个反馈。这是一个例子,你可以改变你的代码
const showFirms = function showSection() {
return new Promise((resolve, reject) => {
// Get the keys for the queries
const keys = SECTIONS.map(x => x || UNSORTED_SECTION_NAME);
// For each sections we gonna call a find request
const promises = SECTIONS.map((x, xi) => {
const query = x ? {
sections: x,
} : {
sections: {
$nin: SECTIONS,
},
};
const key = keys[xi];
return Firms.find(query);
});
// Resolve all promises
Promise.all(promises)
.then((rets) => {
// Use the finds results to build an acc array
const accs = rets.map((x, xi) => ({
section: keys[xi],
firms: x,
}));
// Change the sort -> ;) #comments
const sortedAccs = accs.sort((a, b) => (a.section > b.section));
resolve(sortedAccs);
})
.catch(reject);
});
};
如何使用它
showFirms()
.then(accs => res.render('template', {
sections: accs,
}))
.catch(err => console.log(`I have an error ${err.toString()}`));
看看这段代码的重拍,我们不是一个接一个地获取数据,而是在同一时间(异步)获取数据,然后处理返回 如果你有任何问题,我在这里,这个代码是未经测试,所以给我一个反馈。这是一个例子,你可以改变你的代码
const showFirms = function showSection() {
return new Promise((resolve, reject) => {
// Get the keys for the queries
const keys = SECTIONS.map(x => x || UNSORTED_SECTION_NAME);
// For each sections we gonna call a find request
const promises = SECTIONS.map((x, xi) => {
const query = x ? {
sections: x,
} : {
sections: {
$nin: SECTIONS,
},
};
const key = keys[xi];
return Firms.find(query);
});
// Resolve all promises
Promise.all(promises)
.then((rets) => {
// Use the finds results to build an acc array
const accs = rets.map((x, xi) => ({
section: keys[xi],
firms: x,
}));
// Change the sort -> ;) #comments
const sortedAccs = accs.sort((a, b) => (a.section > b.section));
resolve(sortedAccs);
})
.catch(reject);
});
};
如何使用它
showFirms()
.then(accs => res.render('template', {
sections: accs,
}))
.catch(err => console.log(`I have an error ${err.toString()}`));
基于Grégory NEUTS优秀的解决方案。我简化了一些事情,并使“其他部分案例”起作用。我甚至放弃了排序功能。最终结果将按照在初始
部分数组中声明的部分顺序返回,因此现在我可以对其重新排序以控制输出
const showFirms = function () {
return new Promise ((resolve, reject) => {
const extendedSections = SECTIONS.slice();
extendedSections.push(UNSORTED_SECTION_NAME);
const promises = extendedSections.map((section) => {
const unsortedCase = section === UNSORTED_SECTION_NAME;
const query = unsortedCase ? {sections: {$nin: SECTIONS}} : {sections: section};
return Firms.find(query);
})
Promise.all(promises)
.then((allResponces) => {
const sectionsData = allResponces.map((response, i) => ({
section: extendedSections[i],
firms: response,
}));
resolve(sectionsData);
})
.catch(reject);
});
};
基于Grégory NEUTS优秀的解决方案。我简化了一些事情,并使“其他部分案例”起作用。我甚至放弃了排序功能。最终结果将按照在初始部分数组中声明的部分顺序返回,因此现在我可以对其重新排序以控制输出
const showFirms = function () {
return new Promise ((resolve, reject) => {
const extendedSections = SECTIONS.slice();
extendedSections.push(UNSORTED_SECTION_NAME);
const promises = extendedSections.map((section) => {
const unsortedCase = section === UNSORTED_SECTION_NAME;
const query = unsortedCase ? {sections: {$nin: SECTIONS}} : {sections: section};
return Firms.find(query);
})
Promise.all(promises)
.then((allResponces) => {
const sectionsData = allResponces.map((response, i) => ({
section: extendedSections[i],
firms: response,
}));
resolve(sectionsData);
})
.catch(reject);
});
};
排序不应该成为您对mongodb的请求的一部分吗?如果它的返回值不可预测,我不知道您如何处理查询之外的排序您正在对字符串进行比较。例如:name\u one
name\u two
。这是错误的。这里的问题是我运行多个请求(showSection
是一个递归函数),然后我在累加器acc
中收集所有结果,然后传递给我的模板。如果排序是每个请求的一部分,它只会对每个响应中的元素进行排序。这不是我想要实现的。为什么我不能这样做呢?@GrégoryNEUT?在JavaScript中,a总是小于b,反之亦然。至少它总是会返回一些预测值C可预测的结果。我的代码以随机和不可预测的顺序将acc
传递到我的模板。我想你的意思是if(I==0)
而不是if(I==SECTIONS.length)
排序不应该成为您对mongodb的请求的一部分吗?如果它的返回值不可预测,我不知道您如何处理查询之外的排序您正在对字符串进行比较。例如:name\u one
>name\u two
。这是错误的。这里的问题是我运行了多个请求(showSection
是一个递归函数),然后我在累加器acc
中收集所有结果,然后传递给我的模板。如果排序是每个请求的一部分,它只会对每个响应中的元素进行排序。这不是我想要实现的。为什么我不能这样做呢?@GrégoryNEUT?在JavaScript中,a总是小于b,反之亦然。至少它总是会返回一些预测值C可预测的结果。我的代码以随机和不可预测的顺序将acc
传递到我的模板。我想你的意思是if(I==0)
而不是if(I==SECTIONS.length)
很棒的工作!对我来说有点难理解,因为我是EcmaScript中promises的新手,但它以一种可预测的方式返回我需要的所有内容。我将尝试再做几次解释员,以便对这里发生的事情有更深入的了解。此外,正如我看到的,此解决方案在部分中查询预定义键
array,不返回没有或带有其他值的文档。将尝试进行一些改进。我不明白我的初始代码有什么问题,这仍然令人困惑。我不相信魔术。初始代码中的问题是,您将指向acc
数组的指针发送到您要访问的页面要在第一次find调用后进行渲染。然后异步随机地执行另一个find并填充acc
对象。当您使用acc
时,关于完成并推送到acc
的请求数量是完全随机的。谢谢。我相信我现在看到了最初的问题。我稍微重写了您的代码le bit。看看下面的答案。很棒的工作!对我来说有点难理解,因为我对EcmaScript中的Promissions是新手,但它以一种可预测的方式返回我需要的所有内容。我将尝试作为解释者再工作几次,以获得对这里发生的事情的深入了解。此外,正如我所看到的,此解决方案对