【问题标题】:Conditional count on the basis of an array within an array of subdocuments in mongodb?基于mongodb中子文档数组中的数组的条件计数?
【发布时间】:2021-06-04 00:34:39
【问题描述】:

我有一组聊天记录

    {
      "_id": "60b886babeeb7301c49cd114",
      "participants": [
        "6096c0067a9acc2164f4a14e",
        "6096bfea7a9acc2164f4a14c"
      ],
      "access": [
        "6096c0067a9acc2164f4a14e",
        "6096bfea7a9acc2164f4a14c"
      ],
      "messages": [
        {
          "access": [
            "6096c0067a9acc2164f4a14e"
          ],
          "seen": [
            "6096bfea7a9acc2164f4a14c"
          ],
        "message": "This is message 5",
        "from": "6096bfea7a9acc2164f4a14c",
          "_id": "60b88764da05c21e5483410b",
        },
        
      ],
    },...

我想在请求用户出现在聊天访问列表中的位置恢复聊天,但我还需要发送一些其他信息,例如聊天的最后一条消息和未看到的消息总数。为每个聊天获取总共看不见的消息给我带来了麻烦。在我的脑海中,流程应该是这样的。

  1. 遍历/展开消息数组。
  2. 检查每条消息是否用户在access 列表中,而不是在seen 列表中递增计数。
  3. 将此计数添加到每个聊天对象。

我试图找到一个具有聚合管道、定位项目的纯 mongodb 解决方案,但找不到任何实现上述步骤的方法。

我现在的做法是过滤聊天后在 JavaScript 中遍历光标。

      let messages = chat.messages;      
      let unseenMessages = 0;
      messages.forEach(msg => {
        if (
          msg.access.includes(req.session.userId) &&
          !msg.seen.includes(req.session.userId)
        ) {
          unseenMessages += 1;
          console.log('unseen message', msg.message);
        }
      });

有没有办法在不涉及 JavaScript 的情况下实现这一点?如果您愿意建议对架构进行任何更改,我觉得我的架构设计不是很优化。

【问题讨论】:

  • 聊天中“访问”的目的是什么?您是否在限制来自其他用户的聊天消息?
  • 聊天中的访问列表限制了对整个聊天的访问。每条消息也有一个访问列表,可以进行更精细的控制。

标签: mongodb mongoose


【解决方案1】:

不是答案,但因为您要求根据您当前的模型提供架构设计建议 -

我没有看到数据模型中对消息进行精细控制的重要性。我建议您为聊天应用程序使用 3 个架构。

  1. 聊天 - 这将包含有权访问聊天/群组的用户列表

    {
    "users": {Str(User._id: Object(User)}, // 映射,因为这降低了搜索复杂性
    “消息”:数组(消息)
    }

  2. 用户 - 与聊天的多对多关系。还将存储“最后阅读的消息 id 索引”,用于通过来自 chat.messages.seen_by.append(user._id) 的索引更新“message_seen_by”

    {
    聊天:{ Str(聊天):对象(Str),
    lastMessageReadIndex:数字
    }

  3. 消息 - 与聊天的一对多关系。将存储消息以及用户列表所见。

    {
    聊天:对象(聊天), txt:字符串, seen_by : 数组[用户] }

这是一个虚拟模型,您可以根据自己的喜好进一步更新架构。希望这种方法有所帮助。

【讨论】:

  • 出于几个原因,我希望对消息进行更精细的控制。 1. 如果一方删除了一条消息,我们不希望它从数据库中删除,因此从所有其他方中删除。 2.如果一方删除聊天然后租用它,他们应该无法访问以前的消息,但其他方应该仍然可以访问它们。
  • 在您的情况下,您可以让聊天中的用户也可以作为可见消息使用
猜你喜欢
  • 2017-05-18
  • 2023-03-26
  • 2018-01-26
  • 1970-01-01
  • 2016-12-31
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多