首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MongoDb中计数未读消息

在MongoDb中计数未读消息
EN

Stack Overflow用户
提问于 2022-07-13 15:24:45
回答 2查看 102关注 0票数 1

我试着为用户计算未读消息。在我的模型中,我有一个属性LastMessageDate,它包含组聊天中最后创建的消息的日期。我也有一个成员前一(列表),其中包含成员在小组聊天。每个成员都有一个UserId和LastReadDate属性。当用户在组聊天中写入新消息或用户从组聊天加载消息时,将更新LastReadDate。

现在,我要计算特定用户未读取消息的聊天次数(消息存储在另一个集合中)。我试试看:

代码语言:javascript
复制
var db = GetGroupCollection();

var filter = Builders<ChatGroup>.Filter.Where(p => p.Members.Any(m => m.UserId == userId && m.LastReadDate < p.LastMessageDate));
return await db.CountDocumentsAsync(filter);

但我收到以下错误:

LINQ表达式:{document}{Members}.Where((({document}{UserId} == 730 ddbc7-5d03-4060-b9ef-2913d0b1d7db) AndAlso ({document}{LastReadDate} <{document}{LastMessageDate})具有成员"p“,不能用于构建正确的MongoDB查询。

我该怎么办?有没有更好的解决办法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-14 01:30:03

根据评论中提供的数据,我认为需要聚合查询才能实现结果。

  1. $set -集Members字段 1.1。$filter --以Members数组作为input,过滤文档并匹配当前文档的UserIdLastMessageDate大于($gt)当前文档的LastReadDate
  2. $match -使用Members筛选文档不是一个空数组。
代码语言:javascript
复制
db.groups.aggregate([
  {
    "$set": {
      Members: {
        $filter: {
          input: "$Members",
          cond: {
            $and: [
              {
                $eq: [
                  "$$this.UserId",
                  1
                ]
              },
              {
                $gt: [
                  "$LastMessageDate",
                  "$$this.LastReadDate"
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    $match: {
      Members: {
        $ne: []
      }
    }
  }
])

蒙戈游乐场样本

对于C#语法,可以直接将查询作为字符串提供,也可以将查询转换为BsonDocument语法。

请注意,上面的查询将返回文档数组,因此您需要使用System.Linq来计数返回的文档。

代码语言:javascript
复制
using System.Linq;

var pipeline = new BsonDocument[]
{
    new BsonDocument("$set", 
        new BsonDocument("Members", 
            new BsonDocument("$filter", 
                new BsonDocument
                { 
                    { "input", "$Members" },
                    { "cond", new BsonDocument
                        (
                            "$and", new BsonArray
                            {
                                new BsonDocument("$eq", 
                                    new BsonArray { "$$this.UserId", userId }),
                                new BsonDocument("$gt",
                                    new BsonArray { "$LastMessageDate", "$$this.LastReadDate" })
                            }
                        )
                    }
                }
            )
        )
    ),
    new BsonDocument("$match",
        new BsonDocument("Members",
            new BsonDocument("$ne", new BsonArray())))

};

var db = GetGroupCollection();

return (await db.AggregateAsync<BsonDocument>(pipeline))
    .ToList()
    .Count;
票数 4
EN

Stack Overflow用户

发布于 2022-07-13 16:58:03

当您想查询文档的嵌套列表时,请尝试使用ElemMatch作为解决方案。

代码语言:javascript
复制
var filter = builder.ElemMatch(o => o.Members,m => m.UserId == userId && m.LastReadDate < p.LastMessageDate);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72968801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档