猫鼬计数嵌入数组元素与聚合

时间:2018-11-16 16:16:07

标签: node.js mongoose count aggregate

我目前正在尝试实现一些在SQL中微不足道的东西,但是对于Mongoose / MongoDb 3.3确实很痛苦。

我收藏了一些谈话。对话由发布者开始,由零个或多个消息组成。消息在发行方和用户之间交换,并存储在消息数组中。我的工作很简单,计算给定发行者的未读邮件数。

与一个发行人进行的一次对话可能如下:

{
    "_id" : ObjectId("578caba0264f76ec80d87e7c"),
    "issuer" : ObjectId("578c9c68261246f717343ab7"),
    "messages" : [
        {
            "content" : "Hi !",
            "type" : "text",
            "user" : ObjectId("56582b17b380912011c485e2"),
            "_id" : ObjectId("578caba08cf9a9081927e326"),
            "createdAt" : ISODate("2016-07-18T10:12:48.778Z"),
            "seenAt" : ISODate("2016-07-18T10:13:16.725Z")
        },
        {
            "content" : "Wassup ?",
            "type" : "text",
            "user" : ObjectId("569a9d343bd9840e26797412"),
            "_id" : ObjectId("578cabcb8cf9a9081927e327"),
            "createdAt" : ISODate("2016-07-18T10:13:31.254Z"),
            "seenAt" : ISODate("2016-07-18T10:13:34.133Z")
        },
        {
            "content" : "Fine, ya ?",
            "type" : "text",
            "user" : ObjectId("569a9d343bd9840e26797412"),
            "_id" : ObjectId("578cabd38cf9a9081927e328"),
            "createdAt" : ISODate("2016-07-18T10:13:39.573Z")
        }
    }
}

到目前为止,我尝试使用Mongoose聚合:

function findUnreadByIssuerId(issuerId) {
    return Conversation
    .aggregate()
    .match({ issuer: issuerId })
    .unwind('messages')
    .match({'messages.seenAt' : { $exists: 'false'} })
    .count()
    .exec();
}

这里的意思是,nodejs抱怨count()不是函数。聚合似乎没有其他问题,因为如果删除count(),我将得到一个数组。

然后,我尝试使用$ group,但是我是Mongo及其分组的新手,我得到了一个空数组:

return Conversation .aggregate([
    { $match: { issuer: issuerId } },
    { $unwind: '$messages' },
    { $match: {'messages.seenAt' : { $exists: 'false'} } },
    { $group: {
        _id: '$messages.createdAt',
        count: { $sum: 1 }
    }}
    ])
    .exec();

在提供的示例中,呼叫的预期结果理想情况下为2。但是我可以处理{sum:2},尽管并不理想。我的猫鼬聚合链有什么问题?

1 个答案:

答案 0 :(得分:0)

  

对于Mongo> = 3.4:

您应该为$ count提供一个参数,它是count的列的名称。

https://docs.mongodb.com/manual/reference/operator/aggregation/count/

使用方式:

=VLOOKUP(A1,Sheet1!A:B, 2, FALSE)/Sheet2!B1

它不返回整数而是一个对象 .count("total_unseen")

  

对于Mongo <3.4

使用$ group进行计数:

{total_unseen: 1}

关于结果: 如果管道中的某个阶段为空,则结果为空,但通常驱动程序将其转换为更合适的值。

因此对于这两种方法,当计数为0时,结果将为空数组或null。 (取决于驱动程序)