Meteor/Mongodb - 数组、子文档和重叠订阅

Posted

技术标签:

【中文标题】Meteor/Mongodb - 数组、子文档和重叠订阅【英文标题】:Meteor/Mongodb - arrays, subdocuments & overlapping subscriptions 【发布时间】:2017-04-14 19:41:45 【问题描述】:

我在做游戏;玩家组成联盟并做出相互竞争的预测。联赛是这样的:

 leagueName: "Premier League", 
players:[ 
         name: "Goodie", secretPrediction: "abc", 
         name: "Baddie", secretPrediction: "def" 
        ] 

对于每个玩家,我需要向客户端发布联盟中所有玩家的姓名,但只发布他们自己的秘密预测。所以从上面看,如果 Goodie 登录了,mini-mongo 上的文档应该是:

 leagueName: "Premier League", 
  players:[ 
           name: "Goodie", secretPrediction: "abc", 
           name: "Baddie" 
          ] 

为此,我有两个出版物 - 一个获取整个联盟文档但不包括所有秘密预测,另一个获取玩家数组中当前玩家的子文档包括她的秘密预测。我的出版物是:

// Publish whole players array excluding secretPrediction
Leagues.find("players.name": "Goodie", fields: "players.secretPrediction": 0)

// Publish the whole Goodie item in the players array and nothing else 
Leagues.find("players.name": "Goodie", fields: players: $elemMatch: name: "Goodie")

问题是,当我订阅 both 上述出版物时,我没有得到我想要的文档 - 即使第二个出版物也排除了秘密预测。 (就其本身而言,出版物的行为符合预期,只有当我同时订阅两者时。)

现在,我从this answer 了解到,这两个出版物应该在客户端“合并”

***字段的级别,Meteor 负责在文档之间执行集合并集,以便订阅可以重叠 - 发布将不同***字段发送到客户端工作端的函数在客户端和客户端,集合中的文档将是两组字段的并集。

所以我有两个主要问题(做得好/感谢您到此为止!):

    是否因为我不处理***字段而没有合并文档?有没有办法解决这个问题? 我是不是完全走错了路?有没有更好的方法来获得我想要的结果?

【问题讨论】:

1.正确的。 2. 您可以尝试发布到仅限客户端的“虚拟”集合。 【参考方案1】:

    是的,Meteor 的多个订阅合并仅适用于***字段,在 Meteor 文档中提到:Meteor.subscribe

    我不能说你走错了方向,这真的取决于你的情况,你想帮助什么功能。只说我自己,我会将上述集合解耦为两个单独的集合。因为玩家可能加入很多联赛,联赛可能有很多玩家,所以他们的关系是many-to-many (n-n)。对于这种关系,我们应该将它们拆分为两个集合并使用associative table 来反映它们的关系

所以在你的情况下,我会:

联赛收藏:

[
  _id: 'league1',
  name: 'League 1',
  // ...
]

玩家收藏:

[
  _id: 'player1',
  name: 'Player 1',
  // ...
]

League2Player 收藏:

[
  _id: 'league1palyer1',
  playerId: 'player1',
  leagueId: 'league1',
  secretPrediction: 'abc',
  // ...
]

【讨论】:

文档中的好地方 - 我没有看到那个评论。并且——“我们希望在未来的版本中解除这个限制。” - 希望很快...【参考方案2】:

您是否可以重新排列数据文档,以便您可以使用单个查询,例如

 leagueName: "Premier League", 
players:[ 
         name: "Goodie", 
         name: "Baddie" 
        ] 
playerPredictions:[ 
         name: "Goodie", secretPrediction: "abc", 
         name: "Baddie", secretPrediction: "def" 
        ] 

这样就可以在单个查询中返回所有玩家,并且只返回给定人的 playerPrediction。

【讨论】:

接受这个作为答案,因为我认为这是获得所需结果的最简单、最快捷的方法

以上是关于Meteor/Mongodb - 数组、子文档和重叠订阅的主要内容,如果未能解决你的问题,请参考以下文章

Meteor / MongoDB - 如何证明数组中的任何项目是不是等于特定值,而不是在“真”的情况下从另一个数组中提取项目?

如何将 mongodb 客户端连接到本地 Meteor MongoDB

Meteor mongodb:如何获取第 N 条记录?

Meteor mongodb:如何获取第 N 条记录?

DOM编程技巧以及重排和重绘

根据子文件夹移动和重命名文件