计算忽略重复的文档

时间:2016-11-03 14:22:36

标签: mongodb mongodb-query aggregation-framework

我想计算特定项目中的所有电子邮件(ID:7),但忽略一个广告系列中的重复行。

以下是我的收藏结构示例:

void outputv(std::va_list va)
{
    std::cout << va_arg(va, int);
    std::cout << " ";
    std::cout << va_arg(va, const char *);
    std::cout << "\n";
}

这就是结果:

{
    "_id" : ObjectId("581a9054c274f7b512e8ed94"),
    "email" : "a@example.com",
    "IDproject" : 7,
    "IDcampaign" : 10
}

{
    "_id" : ObjectId("581a9064c274f7b512e8ed95"),
    "email" : "b@example.com",
    "IDproject" : 7,
    "IDcampaign" : 10
}

{
    "_id" : ObjectId("581a9068c274f7b512e8ed96"),
    "email" : "b@example.com",
    "IDproject" : 7,
    "IDcampaign" : 10
}

{
    "_id" : ObjectId("581a906cc274f7b512e8ed97"),
    "email" : "b@example.com",
    "IDproject" : 7,
    "IDcampaign" : 11
}

{
    "_id" : ObjectId("581a9072c274f7b512e8ed98"),
    "email" : "c@example.com",
    "IDproject" : 7,
    "IDcampaign" : 11
}

{
    "_id" : ObjectId("581a9079c274f7b512e8ed99"),
    "email" : "d@example.com",
    "IDproject" : 7,
    "IDcampaign" : 12
}

a@example.com b@example.com b@example.com c@example.com d@example.com (6)。请注意,Total: 5被提及两次。这是因为b@example.com有广告系列10,10和11.我们忽略了一个10。

这是我尝试过的:

b@example.com

但它只返回忽略db.mycollection.aggregate([ {$match : {IDproject : 7}}, {$group : {_id : "$email", total : {$sum : 1}}} ]) 的唯一电子邮件。此外,我可以使用以下查询获得唯一数量的电子邮件:

IDcampaign

但同样,它只会显示忽略db.mycollection.distinct('email', {IDproject : 7}) 的唯一电子邮件。

有人可以提示我如何计算电子邮件,包括IDcampaign吗?

感谢。

P.S。我使用PHP的MongoDB,我可以用PHP计算解决问题,但这不是解决方案。

1 个答案:

答案 0 :(得分:3)

将其作为群组密钥的一部分包含在内,如下例所示:

db.mycollection.aggregate([
    { "$match": { "IDproject": 7 } },
    {
        "$group": {
            "_id": {
                "email" : "$email",                
                "IDcampaign" : "$IDcampaign"
            },
            "count": { "$sum": 1 }
        }
    }
])

示例输出

/* 1 */
{
    "_id" : {
        "email" : "a@example.com",
        "IDcampaign" : 10
    },
    "count" : 1
}

/* 2 */
{
    "_id" : {
        "email" : "d@example.com",
        "IDcampaign" : 12
    },
    "count" : 1
}

/* 3 */
{
    "_id" : {
        "email" : "b@example.com",
        "IDcampaign" : 11
    },
    "count" : 1
}

/* 4 */
{
    "_id" : {
        "email" : "b@example.com",
        "IDcampaign" : 10
    },
    "count" : 2
}

/* 5 */
{
    "_id" : {
        "email" : "c@example.com",
        "IDcampaign" : 11
    },
    "count" : 1
}

要回答您关于获取计数的后续问题,因为您不需要电子邮件列表,您可以运行以下管道

db.mycollection.aggregate([
    { "$match": { "IDproject": 7 } },
    {
        "$group": {
            "_id": null,
            "count": { "$sum": 1 },
            "emails": {
                "$addToSet": {
                    "email" : "$email",                
                    "IDcampaign" : "$IDcampaign"
                }
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "count": 1,
            "total": { "$size": "$emails" }
        }
    }
])

给你结果

{        
    "total" : 5,
    "count" : 6
}

您可以将其解释为Total 5 (of 6)