简体   繁体   English

MongoDB(mongoose)聚合集合中特定ObjectID的计数实例

[英]MongoDB (mongoose) aggregate count instances of specific ObjectIDs in collection

Assuming I have a schema that looks something like this: 假设我的模式看起来像这样:

{
    field: [{
        subDoc: ObjectId,
        ...
    }],
    ...
}

and I have some list of ObjectIds (user input), how would I get a count of those specific ObjectIds? 我有一些ObjectIds(用户输入)列表,我如何得到这些特定ObjectIds的计数? For exmaple, if I have data like this: 例如,如果我有这样的数据:

[
    {field: [ {subDoc: 123}, {subDoc: 234} ]},
    {field: [ {subDoc: 234}, {subDoc: 345} ]},
    {field: [ {subDoc: 123}, {subDoc: 345}, {subDoc: 456} ]}
]

and the list of ids given by the user is 123, 234, 345 , I need to get a count the given ids, so a result approximating this: 与用户给定ID列表是123, 234, 345 ,我需要得到一个数给定的ID,所以结果是近似的:

{
    123: 2,
    234: 2,
    345: 2
}

What would be the best way to go about this? 最好的方法是什么?

The aggregation framework itself if not going to dynamically name keys the way you have presented as a proposed output, and that probably is a good thing really. 聚合框架本身如果不按照你提出的输出方式动态命名键,那真的是一件好事。 But you can probably just do a query like this: 但你可以像这样做一个查询:

db.collection.aggregate([
    // Match documents that contain the elements
    { "$match": { 
        "field.subDoc": { "$in": [123,234,345] }
    }},

    // De-normalize the array field content
    { "$unwind": "$field" },

    // Match just the elements you want
    { "$match": { 
        "field.subDoc": { "$in": [123,234,345] }
    }},

    // Count by the element as a key
    { "$group": {
        "_id": "$field.subDoc",
        "count": { "$sum": 1 }
    }}
])

That gives you output like this: 这给你输出如下:

{ "_id" : 345, "count" : 2 }
{ "_id" : 234, "count" : 2 }
{ "_id" : 123, "count" : 2 }

But if you really want to go nuts on this, you are specifying the "keys" that you want as part of your query, so you could form a pipeline like this: 但是,如果您真的想要坚持这一点,那么您在查询中指定了所需的“键”,因此您可以形成如下管道:

db.collection.aggregate([
    { "$match": { 
        "field.subDoc": { "$in": [123,234,345] }
    }},
    { "$unwind": "$field" },
    { "$match": { 
        "field.subDoc": { "$in": [123,234,345] }
    }},
    { "$group": {
        "_id": "$field.subDoc",
        "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": null,
        "123": { 
            "$max": {
                "$cond": [
                    { "$eq": [ "$_id", 123 ] },
                    "$count",
                    0
                ]
            }
        },
        "234": { 
            "$max": {
                "$cond": [
                    { "$eq": [ "$_id", 234 ] },
                    "$count",
                    0
                ]
            }
        },
        "345": { 
            "$max": {
                "$cond": [
                    { "$eq": [ "$_id", 345 ] },
                    "$count",
                    0
                ]
            }
        }
    }}
])

Which is a relatively simple thing to construct that last stage in code by just processing the list of arguments: 通过处理参数列表,在代码中构造最后一个阶段是一件相对简单的事情:

var list = [123,234,345];

var group2 = { "$group": { "_id": null } };

list.forEach(function(id) {
    group2["$group"][id] = { 
        "$max": {
            "$cond": [
                { "$eq": [ "$_id", id ] },
                "$count",
                0
            ]
        }
    };
});

And that comes out more or less how you want it. 而这或多或少都是你想要的。

{ 
    "_id" : null, 
    "123" : 2, 
    "234" : 2, 
    "345" : 2 
}

Not exactly what you're asking for but it can give you an idea: 不完全是你要求的,但它可以给你一个想法:

    db.test.aggregate([
    {
        $unwind: '$field'
    },
    {
        $group: {
            _id: {
                subDoc: '$field.subDoc'
            },
            count: {
                $sum: 1
            }
        }
    },
    {
        $project: {
            subDoc: '$subDoc.subDoc',
            count: '$count'
        }
    }
]);

Output: 输出:

 {
    "result": [
        {
            "_id": {
                "subDoc": 456
            },
            "count": 1
        },
        {
            "_id": {
                "subDoc": 345
            },
            "count": 2
        },
        {
            "_id": {
                "subDoc": 234
            },
            "count": 2
        },
        {
            "_id": {
                "subDoc": 123
            },
            "count": 2
        }
    ],
    "ok": 1
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM