Javascript 流星中的分裂群

Javascript 流星中的分裂群,javascript,node.js,mongodb,meteor,Javascript,Node.js,Mongodb,Meteor,我有一个集合行,其中包含字段group1、group2和group3,这些字段都是数字 我可以将该系列与 Template.tplName.helpers({ rows: function() { return Rows.find({}); }, }); 及 我想把第一页列出来 <li><a href="?">1</a></li> <li><a href="?">2</a></li>

我有一个集合
,其中包含字段
group1
group2
group3
,这些字段都是数字

我可以将该系列与

Template.tplName.helpers({
  rows: function() {
    return Rows.find({});
  },
});

我想把第一页列出来

<li><a href="?">1</a></li>
<li><a href="?">2</a></li>
<li><a href="?">1</a></li>
<li><a href="?">2</a></li>
<li><a href="?">1</a></li>
<li><a href="?">2</a></li>
<li><a href="?">3</a></li>
给我唯一的
group1
编号。现在,我需要某种方法来告诉路由器(或其他东西),我已经单击了
group1
编号中的一个,并且在下一条路由上有
rows=rows.find({group1:?})
,而不是显示所有的行

但是,如果我使用
\uuu.pulk()
我会将组号作为一个列表,这可能是删除重复项的最简单方法,但我还需要求和

我想我可以创建一个模板

<template name="groupList">
  {{#each groups}}
    <p><a href="?">{{name}}</a> (amount: {{amount}})</p>
  {{/each}}
</template>
单击其中一个group1链接后,一个新路由处于活动状态,显示属于单击的group1链接的所有group2对象。 因此,如果用户在第一组链接中点击“1”,可能是这样的

this.route('groupListSecond', {
  path: '/groups',
  template: 'groupList',
  waitOn: function() {
    return [
      subs.subscribe('groups'),
    ]
  },
  data: function() {
    var group2List = [
      {
        name: "1",
        amount: 200 + 300,
      },
      {
        name: "2",
        budget: 250 + 220 + 200,
      },
    ];

    return {
      groups: group2List,
    }
  },
});
如果用户在group2链接中进一步单击1,则为

this.route('groupListThird', {
  path: '/groups',
  template: 'groupList',
  waitOn: function() {
    return [
      subs.subscribe('groups'),
    ]
  },
  data: function() {
    var group3List = [
      {
        name: "1",
        amount: 200,
      },
    ];

    return {
      groups: group3List,
    }
  },
});
这些路由是手动创建的,因为我不知道如何自动创建和注册用户单击的链接,并且只显示与此组相关的对象


我想这应该从集合中完成,每个文档中都有多个组号,但是如果我不能使用这种结构,我将不得不将每个组分成单独的集合。

一个包含很多部分的长问题!因此,这将是一个包含很多部分的长答案。请原谅我:

第1部分:聚合 不,Meteor还不支持mongo级别的聚合。有用于此的包(在服务器上),但没有客户端mini-mongo。因此,您需要提取所有记录并自己完成这项工作(目前),这是正确的。但是,您还提到要对数据进行求和(我认为这是基于注释的会计),因此
\uu.pull()
不够好。也许您可以在
..map()
中使用
..groupBy()
..reduce()
——可能是这样的:

var group1Totals = _.map(_.groupBy(rows, "group1"), function(documents, key) {
  return {groupId: key,
          total: _.reduce(documents, function(acc, doc) {
                   return acc += doc.amount;
                 }, 0)};
};
这将为您提供一个新的对象数组(称为
group1Totals
),其中包含
group1
total
属性。这足以作为模板助手返回(Meteor将遍历
{{{each}}
块中的数组和游标)。您可以稍后重用此代码,仅获取组2的总计,但不必从所有(
)开始,您可以使用
\u.filter()
并按“group2”分组,将筛选后的列表传递到
\u.groupBy()

第2部分:路由 Iron路由器确实允许设置数据上下文。您需要定义包含参数的路由,然后设置链接以传递这些参数。同样,您的路线示例可能是:

Router.route('/group1/:groupId', {
  data: function() {
    var groupId = this.params.groupId;
    return Rows.find({group1: groupId});
  }
});
这会将模板的数据上下文(
This
)设置为所选行的子集。但是,您还需要确保链接使用正确的参数调用路由。Iron Router还为此提供了一个内置帮助程序,
pathFor
,您可以在模板中这样使用它(使用上面定义的结构):


{{#每组}

(金额:{{total}})

{{/每个}}
然后,你应该对你的三个小组中的每一个重复这一步骤(进行适当的调整)。请记住,组2需要在其
.find()
选择中同时包含组1和组2,因此您可能需要两个路由参数

尾注 考虑到您当前的结构,这可能是最简单的方法。我不确定非规范化是否适合或需要会计系统。甚至使用NoSQL来解决这个问题!但是,我假设你是在用它来报告,而不是录音。这里的解决方案是严格的三组方法,其他组需要手动添加。您可以更动态地做事情,但您当前的数据结构并不适合这样做。您可能需要查看层次关系和节点与叶结构。远远超出了这个问题的范围


我想这就是您需要/要求的一切。

我不明白您的数据以及如何将每条记录分成几页(没有,1,2)???group1到group3的含义是什么?与其在您至少想再次拆分时将每个组存储到每个记录,不如将值存储为group1、group2、group3的三个记录(集),例如:{group:1,values:[1,2]},{group:2,values:[1,2]},{group:3,values:[1,2,3]}如果问题不清楚,请原谅。我有一个收藏组。但是我没有列出所有的组,而是创建了某种映射。因此,我在组集合中添加了一些字段以指示/模拟某些级别。您需要告诉我们组的含义。它看起来像一个会计系统&
group1
可能意味着
金额
预算
,这将破坏实体完整性,这意味着我99%确定您的ER模型是错误的,但无法用假名称修复它。它实际上是一个“多层次”的会计计划。因此,组是嵌套的。但是我不需要存储关于不同组的任何信息(除了最后一个/最深的级别),所以我认为我可以只存储1个级别,并用其他字段指示嵌套级别,指示“分支”。
this.route('groupListSecond', {
  path: '/groups',
  template: 'groupList',
  waitOn: function() {
    return [
      subs.subscribe('groups'),
    ]
  },
  data: function() {
    var group2List = [
      {
        name: "1",
        amount: 200 + 300,
      },
      {
        name: "2",
        budget: 250 + 220 + 200,
      },
    ];

    return {
      groups: group2List,
    }
  },
});
this.route('groupListThird', {
  path: '/groups',
  template: 'groupList',
  waitOn: function() {
    return [
      subs.subscribe('groups'),
    ]
  },
  data: function() {
    var group3List = [
      {
        name: "1",
        amount: 200,
      },
    ];

    return {
      groups: group3List,
    }
  },
});
var group1Totals = _.map(_.groupBy(rows, "group1"), function(documents, key) {
  return {groupId: key,
          total: _.reduce(documents, function(acc, doc) {
                   return acc += doc.amount;
                 }, 0)};
};
Router.route('/group1/:groupId', {
  data: function() {
    var groupId = this.params.groupId;
    return Rows.find({group1: groupId});
  }
});
<template name="groupList">
  {{#each groups}}
    <p>
      <a href="{{pathFor route='group1' groupId=groupId}}">
        {{name}}
      </a>
      (amount: {{total}})
    </p>
  {{/each}}
</template>