MongoDB -统计未读消息

wko9yo5t  于 2023-01-12  发布在  Go
关注(0)|答案(2)|浏览(135)

我尝试为用户统计未读消息。
在我的模型中,我有一个属性,LastMessageDate,包含群聊中最后一条消息的创建日期。(列表),其中包含群聊中的成员。每个成员都具有UserIdLastReadDate属性。LastReadDate在用户在群聊中写入新消息时或者在用户从群聊加载消息时更新。
现在,我想统计特定用户有未读消息的聊天次数(这些消息存储在另一个集合中)。

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表达式:{文档}{成员}。其中((({文档}{用户ID} == 730 ddbc 7 - 5d 03 -4060-b 9 ef-2913 d 0 b1 d 7 db)AndAlso({文档}{最后读取日期}〈{文档}{最后消息日期})))有成员“p”,不能用于构建正确的MongoDB查询。
我该怎么办?有更好的解决办法吗?

7vux5j2d

7vux5j2d1#

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

  1. $set-设置Members字段
    1.1. $filter-Members数组为input时,筛选与当前文档的UserId匹配且LastMessageDate大于($gt)当前文档的LastReadDate的文档。
  2. $match-使用Members不是空数组筛选文档。
db.groups.aggregate([
  {
    "$set": {
      Members: {
        $filter: {
          input: "$Members",
          cond: {
            $and: [
              {
                $eq: [
                  "$$this.UserId",
                  1
                ]
              },
              {
                $gt: [
                  "$LastMessageDate",
                  "$$this.LastReadDate"
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    $match: {
      Members: {
        $ne: []
      }
    }
  }
])

Sample Mongo Playground
对于C#语法,可以直接将查询作为字符串提供,也可以将查询转换为BsonDocument语法。
注意,上面的查询将返回文档数组,因此您需要使用 System.Linq 来计算返回的文档。

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;
bxjv4tth

bxjv4tth2#

当您想要查询文档的嵌套列表时,ElemMatch是您的解决方案,请尝试

var filter = builder.ElemMatch(o => o.Members,m => m.UserId == userId && m.LastReadDate < p.LastMessageDate);

相关问题