【问题标题】:Meteor/Mongodb - arrays, subdocuments & overlapping subscriptionsMeteor/Mongodb - 数组、子文档和重叠订阅
【发布时间】: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.正确的。 2. 您可以尝试发布到仅限客户端的“虚拟”集合。

标签: mongodb meteor publish-subscribe subdocument minimongo


【解决方案1】:
  1. 是的,Meteor 的多个订阅合并仅适用于顶级字段,在 Meteor 文档中提到:Meteor.subscribe

  2. 我不能说你走错了方向,这真的取决于你的情况,你想帮助什么功能。只说我自己,我会将上述集合解耦为两个单独的集合。因为玩家可能加入很多联赛,联赛可能有很多玩家,所以他们的关系是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。

【讨论】:

  • 接受这个作为答案,因为我认为这是获得所需结果的最简单、最快捷的方法
猜你喜欢
  • 2015-11-29
  • 2014-10-10
  • 2017-09-05
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 2015-10-03
  • 1970-01-01
  • 2016-10-17
相关资源
最近更新 更多