Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 多个查询以不可预测的排序结果结束_Javascript_Node.js_Mongodb_Express_Mongoose - Fatal编程技术网

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是新手,但它以一种可预测的方式返回我需要的所有内容。我将尝试作为解释者再工作几次,以获得对这里发生的事情的深入了解。此外,正如我所看到的,此解决方案对