如何";更改“;Meteor/mongo中已发布的字段集

如何";更改“;Meteor/mongo中已发布的字段集,meteor,meteor-publications,Meteor,Meteor Publications,是否有人知道如何根据登录用户记录的某些特征/字段值“更改”出版物(Meteor.publish或Meteor.publishComposite)中的字段集 我使用的是publishComposite,游标处于同一级别,如下所示: Meteor.publishComposite("games", [ { find: userRecord, children: [ { find: gamesWeArePlaying }

是否有人知道如何根据登录用户记录的某些特征/字段值“更改”出版物(Meteor.publish或Meteor.publishComposite)中的字段集

我使用的是publishComposite,游标处于同一级别,如下所示:

Meteor.publishComposite("games", [
  {
    find: userRecord,
    children: [
      {
        find: gamesWeArePlaying
      }
    ]
  },
  {
    find: userRecord,
    children: [
      {
        find: gamesWeOwn
      }
    ]
  },
  {
    find: userRecord,
    children: [
      {
        find: examineWithAnalysis
      }
    ]
  },
  {
    find: userRecord,
    children: [
      {
        find: examineWithoutAnalysis
      }
    ]
  },
  {
    find: userRecord,
    children: [
      {
        find: allGames
      }
    ]
  }
]);
每个find函数都返回一个带有限定记录的游标,以及该用户在该状态下允许的字段集。请注意,在每个子项查找中,它将查找一组唯一的记录,但它返回的字段特定于该游标。最常见的是从“游戏正在玩”到“检查分析”,对于教师/学生,“检查分析”到“检查分析”

但实际情况是,当游戏(即单个记录)从一个光标转换到另一个光标时,底层框架无法向客户端发送正确的“已更改”字段。minimongo记录变得异常,甚至与服务器数据库中的实际内容都不匹配


所以,我的问题是:根据记录的特征,返回一组记录的最佳方法是什么?每个记录都返回一个特定的字段集?

我通读了您的github代码,您的真正意图似乎是发布该用户应该“访问”的所有游戏您希望用户对每个游戏具有不同的权限。这更像是一个
mongodb
解决方案,您希望有一个正常的发布(不是复合发布,它们速度慢而且工作不好),首先获取用户ID。然后只需像这样查询所有游戏(因为您已经是复合发布)

{
  $or : [
    { isolation_group : user.isolation_group }, // part of the user's isolation group
    { owner           : user._id }              // games we own
  ]
}
let gamesWeArePlaying = _.compact(_.map(ArrayOfAllGames, (game, key) => {
  if (game.status !== "playing" || 
        (game.white.id !== user._id && game.black.id !== user._id)) {
    return '';
  }

  return _.pick(game, [
    "black", "clocks", "fen", "lag", "observers", "pending",
    "rated", "rating_type", "startTime", "status", "tomove",
    "variations", "white", "wild"
  ]);
}));
这将根据用户的隔离组或所有权检索用户应该知道的所有游戏。为了简化查询,我建议将
isolation\u组添加到您自己的游戏中,但这是可选的。在检索完所有这些游戏后,您将把它们放在一个数组中,这就是像
lodash
这样的库向我们提供帮助的地方-您可以执行一系列
\uuu.map()
这样的调用

{
  $or : [
    { isolation_group : user.isolation_group }, // part of the user's isolation group
    { owner           : user._id }              // games we own
  ]
}
let gamesWeArePlaying = _.compact(_.map(ArrayOfAllGames, (game, key) => {
  if (game.status !== "playing" || 
        (game.white.id !== user._id && game.black.id !== user._id)) {
    return '';
  }

  return _.pick(game, [
    "black", "clocks", "fen", "lag", "observers", "pending",
    "rated", "rating_type", "startTime", "status", "tomove",
    "variations", "white", "wild"
  ]);
}));

如果你像你在
中提到的那样发布它们,那么这里就有点麻烦了。添加/更改/删除
到相同的
客户端集合
你一定会得到相同的游戏,但是你想根据多个
.map()
调用的结果用特定的字段来显示它。如果您多次添加同一游戏,Meteor将以不同的权限多次发布同一游戏,这不是您想要的。因此,修改该映射调用,以一次实际检查所有权限(即游戏正在玩、游戏下载、检查分析等),并基于此更改
\uuu.pick()
字段列表。这将为您提供一个统一的游戏阵列,其中包含要发布的适当字段,这些字段将得到反应性更新。

好的,伙计们,我发现了这一点,这是我一个愚蠢的程序员错误。首先,让我声明publishComposite和不断变化的字段(撇开所谓的性能问题不谈)实际上是有效的!像这样的方法确实有效:

publishComposite("publication", {
   find() {return collection1.find()},
   children: [
      {find(c1_record) {return collection2.find({s1},{fields: {f1: 1}})}}
      {find(c1_record) {return collection2.find({s2},{fields: {f1: 1, f2: 1}})}}
      {find(c1_record) {return collection2.find({s3},{fields: {f2: 1}})}}
   ]
});
Mongo、Meteor、DDP、客户和minimongo对此没有任何问题。它工作得很好

我的问题是,当使用publishComposite时,如果更高级别的查找不用于发布,而仅用于符合条件的子记录,则必须非常小心。让我们用我的例子。在上面,我发布了游戏记录,并基于特定状态发布了特定字段(如果你在玩,如果你能看到计算机分析,等等)

但是,在其他地方,我必须发布聊天记录。为了正确发布聊天记录,我必须弄清楚用户在玩或观察什么游戏。他们是在玩还是能看到电脑分析并不重要。我只是想知道他们在玩什么游戏。所以我这样做了:

publishComposite("chat", {
find() {
  return Meteor.users.find({_id:...})
},
children[
  {
    find() {return gamescollection.find({..all games user is involved with...})}, 
    children: [{
      find(){
        chat.find({...chats for game...})}
    }]
  }
]
});
看到问题了吗

顶级find发布用户记录、所有字段(可能的问题#1!)

第二级查找发布游戏记录,所有字段都在其荣耀中。我的朋友们,这就是问题所在。我只是没有把这些放在一起,因为我不是故意发布用户或游戏的,只是为了提供发布最低级别聊天记录所需的数据


我更改了后一个发布,只返回用户参与的游戏记录的ID(即,
gamescollection.find({…},{fields:{u ID:1})
,就这样,一切都成功了。

请您提供实际代码以及给定数据和预期结果的示例好吗?我们可以整天进行理论推导,但有可靠的案例进行研究总是很有帮助的。这两个都很有挑战性。如果您真的想知道,您可以在上找到实际代码。预期结果是更具挑战性。基本上,服务器没有发送与添加/删除字段匹配的minimongo更新。这就是为什么我像我一样问这个问题。更容易问一个理论问题:“如果我有记录,{f1:“1”,f2:“a”,f3:“b”,等等},我如何根据f1的值发布具有不同字段的同一记录?这与我现在所做的不完全相同,但很接近。很抱歉反应太晚,我想处理您的问题的最佳方法是将您的发布拆分为较小的发布,以避免多次重新运行试图修改相同的发布命名空间。`` Meteor `.publishComposite(“GamesWarePlaying”,[{find:userRecord,children:[{find:GamesWarePlaying}]})Meteor.publishComposite(“检查分析”,[{find:userRecord,children:[{find:检查分析}])//等等``是的,目前这似乎也是我唯一能看到的。正如我们所说的,我正在努力建立我自己的低级别公众