Mongodb 比较2个计数聚合

Mongodb 比较2个计数聚合,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我在MongoDB中有一个类似以下内容的集合: { "_id" : 1, "type" : "start", userid: "101", placementid: 1 } { "_id" : 2, "type" : "start", userid: "101", placementid: 2 } { "_id" : 3, "type" : "start", userid: "101", placementid: 3 } { "_id" : 4, "type" : "end", userid:

我在MongoDB中有一个类似以下内容的集合:

{ "_id" : 1, "type" : "start", userid: "101", placementid: 1 }
{ "_id" : 2, "type" : "start", userid: "101", placementid: 2 }
{ "_id" : 3, "type" : "start", userid: "101", placementid: 3 }
{ "_id" : 4, "type" : "end", userid: "101", placementid: 1 }
{ "_id" : 5, "type" : "end", userid: "101", placementid: 2 }
我想通过
userid
然后
placementid
对结果进行分组,然后计算“开始”和“结束”的类型,但仅当这两个计数不同时。在这个特定的示例中,我希望获得
placementid:3
,因为当分组并计数时,这是计数不匹配的唯一情况

我已经编写了一个查询,可以获取2个计数和分组,但是当计数不匹配时,我无法进行过滤。这是我的疑问:

db.getCollection('mycollection').aggregate([
    {
        $project: {
            userid: 1,
            placementid: 1,
            isStart: { 
                $cond: [ { $eq: ["$type", "start"] }, 1, 0] 
            },
            isEnd: { 
                $cond: [ { $eq: ["$type", "end"] }, 1, 0] 
            }
        }
    },
    {
        $group: {
            _id: { userid:"$userid", placementid:"$placementid" }, 
            countStart:{ $sum: "$isStart" },
            countEnd: { $sum: "$isEnd" }
        }
    },
    {
        $match: {
            countStart: {$ne: "$countEnd"}
        }
    }
])
似乎我没有正确使用匹配聚合,因为我看到的结果是
countStart
countEnd
相同

{ "_id" : {"userid" : "101", "placementid" : "1"}, "countStart" : 1.0, "countEnd" : 1.0 }
{ "_id" : {"userid" : "101", "placementid" : "2"}, "countStart" : 1.0, "countEnd" : 1.0 } 
{ "_id" : {"userid" : "101", "placementid" : "3"}, "countStart" : 1.0, "countEnd" : 0 } 

有人能指出正确的方向吗?

要比较MongoDB 3.6中提供的所需的
$match
阶段中的两个字段:

db.myCollection.aggregate([
    {
        $project: {
            userid: 1,
            placementid: 1,
            isStart: { 
                $cond: [ { $eq: ["$type", "start"] }, 1, 0] 
            },
            isEnd: { 
                $cond: [ { $eq: ["$type", "end"] }, 1, 0] 
            }
        }
    },
    {
        $group: {
            _id: { userid:"$userid", placementid:"$placementid" }, 
            countStart:{ $sum: "$isStart" },
            countEnd: { $sum: "$isEnd" }
        }
    },
    {
        $match: {
            $expr: { $ne: [ "$countStart", "$countEnd" ] }
        }
    }
])
如果您使用的是旧版本的MongoDB,则可以使用:


要比较MongoDB 3.6中提供的
$match
阶段中的两个字段:

db.myCollection.aggregate([
    {
        $project: {
            userid: 1,
            placementid: 1,
            isStart: { 
                $cond: [ { $eq: ["$type", "start"] }, 1, 0] 
            },
            isEnd: { 
                $cond: [ { $eq: ["$type", "end"] }, 1, 0] 
            }
        }
    },
    {
        $group: {
            _id: { userid:"$userid", placementid:"$placementid" }, 
            countStart:{ $sum: "$isStart" },
            countEnd: { $sum: "$isEnd" }
        }
    },
    {
        $match: {
            $expr: { $ne: [ "$countStart", "$countEnd" ] }
        }
    }
])
如果您使用的是旧版本的MongoDB,则可以使用:


您可以运行以下管道来实现此目的-无需使用$expr或$redact或任何特殊的工具:

db.mycollection.aggregate({
    $group: {
        _id: {
            "userid": "$userid",
            "placementid": "$placementid"
        },
        "sum": {
            $sum: {
                $cond: {
                    if: { $eq: [ "$type", "start" ] },
                    then: 1, // +1 for start
                    else: -1 // -1 for anything else
                }
            }
        }
    }
}, {
    $match: {
        "sum": { $ne: 0 } // only return the non matching-up ones
    }
})

您可以运行以下管道来实现此目的-无需使用$expr或$redact或任何特殊的工具:

db.mycollection.aggregate({
    $group: {
        _id: {
            "userid": "$userid",
            "placementid": "$placementid"
        },
        "sum": {
            $sum: {
                $cond: {
                    if: { $eq: [ "$type", "start" ] },
                    then: 1, // +1 for start
                    else: -1 // -1 for anything else
                }
            }
        }
    }
}, {
    $match: {
        "sum": { $ne: 0 } // only return the non matching-up ones
    }
})

哦,我很接近。谢谢你的提示,它现在起作用了:)哦,我很接近。谢谢你的提示,它正在工作:)