sql >> データベース >  >> NoSQL >> MongoDB

MongoDBドキュメントの再形成

    これは、各カテゴリの期間で上位2つを見つける集計です(サンプル出力と一致しているように見える「タイ」を任意に解除します):

    var pregroup = { "$group" : {
            "_id" : {
                "type" : "$tracked_item_type",
                "name" : "$tracked_item_name"
            },
            "duration" : {
                "$sum" : "$duration"
            }
        }
    };
    var sort = { "$sort" : { "_id.type" : 1, "duration" : -1 } };
    var group1 = { "$group" : {
            "_id" : "$_id.type",
            "num1" : {
                "$first" : {
                    "name" : "$_id.name",
                    "dur" : "$duration"
                }
            },
            "other" : {
                "$push" : {
                    "name" : "$_id.name",
                    "dur" : "$duration"
                }
            },
        "all" : {
            "$push" : {
                "name" : "$_id.name",
                "dur" : "$duration"
            }
        }
        }
    };
    var unwind = { "$unwind" : "$other" };
    project = {
        "$project" : {
            "keep" : {
                "$ne" : [
                    "$num1.name",
                    "$other.name"
                ]
            },
            "num1" : 1,
            "all" : 1,
            "other" : 1
        }
    };
    var match = { "$match" : { "keep" : true } };
    var sort2 = { "$sort" : { "_id" : 1, "other.dur" : -1 } };
    var group2 = { "$group" : {
            "_id" : "$_id",
            "numberOne" : {
                "$first" : "$num1"
            },
            "numberTwo" : {
                "$first" : "$other"
            },
        "all" : {
            "$first" : "$all"
        }
        }
    };
    unwind2 = { "$unwind" : "$all" };
    project2 = { "$project" : {
        "_id" : 0,
        "tracked_item_type" : "$_id",
        "tracked_item_name" : {
            "$cond" : [
                {
                    "$or" : [
                        {
                            "$eq" : [
                                "$all.name",
                                "$numberOne.name"
                            ]
                        },
                        {
                            "$eq" : [
                                "$all.name",
                                "$numberTwo.name"
                            ]
                        }
                    ]
                },
                "$all.name",
                null
            ]
        },
        "duration" : {
            "$cond" : [
                {
                    "$or" : [
                        {
                            "$eq" : [
                                "$all.name",
                                "$numberOne.name"
                            ]
                        },
                        {
                            "$eq" : [
                                "$all.name",
                                "$numberTwo.name"
                            ]
                        }
                    ]
                },
                "$all.dur",
                null
            ]
        }
    }
    }
    match2 = { "$match" : { "tracked_item_name" : { "$ne" : null } } };
    

    サンプルデータでこれを実行する:

    db.top2.aggregate(pregroup, sort, group1, unwind, project, match, sort2, group2, unwind2, project2, match2).toArray()
    [
        {
            "tracked_item_type" : "Software",
            "tracked_item_name" : "Word",
            "duration" : 9540
        },
        {
            "tracked_item_type" : "Software",
            "tracked_item_name" : "Notepad",
            "duration" : 4000
        },
        {
            "tracked_item_type" : "Site",
            "tracked_item_name" : "Digital Blasphemy",
            "duration" : 8000
        },
        {
            "tracked_item_type" : "Site",
            "tracked_item_name" : "Facebook",
            "duration" : 7920
        }
    ]
    

    これは任意の数のドメイン(異なる追跡アイテムタイプ値)で機能し、事前にすべての名前を知っている必要はありません。ただし、それをトップ3、トップ4、トップ5などに一般化すると、追加のトップ「N」値ごとにさらに4つのステージが追加されます。これは、あまり実用的でもきれいでもありません。

    このjiraチケットに投票して、集約フレームワークの「トップN」機能のよりネイティブな実装を取得してください。



    1. Express+MongoDBに最適なセッションストレージミドルウェア

    2. アクティブジョブ/バックグラウンドジョブにファイルを渡す

    3. ソートされたセットRedisをどのように組み合わせるのですか?

    4. ObjectIdへのMongoDB集約プロジェクト文字列