MongoDB aggregate

 $match: same as find

> db.users.aggregate([{$match:{name:"user164"}}])
{ "_id" : ObjectId("5f7c234602c41bd39db9af76"), "name" : "user164" }
{ "_id" : ObjectId("5f7c234c02c41bd39db9af77"), "name" : "user164" }
{ "_id" : ObjectId("5f7c23f702c41bd39db9af78"), "name" : "user164", "comments" : "abc" }

$project: reduce output to specific fields
> db.users.aggregate([{$match:{name:"user164"}},{$project:{_id:0,"name":1}}])
{ "name" : "user164" }
{ "name" : "user164" }
{ "name" : "user164" }


$limit: limit processing data size
> db.users.aggregate([{$match:{name:"user164"}},{$project:{_id:0,"name":1}},{$limit:2}])
{ "name" : "user164" }
{ "name" : "user164" }

$sort: sort by specific field
> db.users.aggregate([{$match:{age:{$gt:10}}},{$project:{_id:0,"name":1,age:1}},{$limit:5},{$sort:{age:1}}])
{ "name" : "user4", "age" : 70 }
{ "name" : "user3", "age" : 84 }
{ "name" : "user0", "age" : 113 }
{ "name" : "user2", "age" : 114 }
{ "name" : "user1", "age" : 115 }

$skip records
> db.users.aggregate([{$match:{age:{$gt:10}}},{$project:{_id:0,"name":1,age:1}},{$skip:5},{$limit:5},{$sort:{age:1}}])
{ "name" : "user10", "age" : 22 }
{ "name" : "user6", "age" : 28 }
{ "name" : "user7", "age" : 36 }
{ "name" : "user9", "age" : 63 }
{ "name" : "user5", "age" : 88 }

define new attribute when $project
// update embedded object to one user
> db.users.updateOne({"name":"user1956"},{$set:{"aa":{"bb":"cc"}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

// show aa.bb by element by $project
> db.users.aggregate([{$match:{age:{$gt:10}}},{$project:{_id:0,"name":1,age:1,"name2":"$name","bb":"$aa.bb"}},{$skip:5}])
{ "name" : "user1864", "age" : 11, "name2" : "user1864" }
{ "name" : "user1907", "age" : 11, "name2" : "user1907" }
{ "name" : "user1929", "age" : 11, "name2" : "user1929" }
{ "name" : "user1956", "age" : 11, "name2" : "user1956", "bb" : "cc" }

$unwind
// prepare data
> db.unwinddata.insertOne({"k1":"v1","k2":"v2","k3":["e1","e2","e3"]})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5f833438651639530e9c2b82")
}
> db.unwinddata.updateOne({},{$set:{"k4":{"k5":["e4","e5","e6"]}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.unwinddata.find().pretty()
{
    "_id" : ObjectId("5f833438651639530e9c2b82"),
    "k1" : "v1",
    "k2" : "v2",
    "k3" : [
        "e1",
        "e2",
        "e3"
    ],
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    }
}

// match data in array
> db.unwinddata.aggregate({$match:{"k4.k5":"e4"}}, {$project:{_id:0}}).pretty()
{
    "k1" : "v1",
    "k2" : "v2",
    "k3" : [
        "e1",
        "e2",
        "e3"
    ],
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    }
}

// unwind k3 array
> db.unwinddata.aggregate({$match:{"k4.k5":"e4"}}, {$unwind: "$k3"}, {$project:{_id:0}}).pretty()
{
    "k1" : "v1",
    "k2" : "v2",
    "k3" : "e1",
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    }
}
{
    "k1" : "v1",
    "k2" : "v2",
    "k3" : "e2",
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    }
}
{
    "k1" : "v1",
    "k2" : "v2",
    "k3" : "e3",
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    }
}

// project attribute from embedded object
> db.unwinddata.aggregate({$match:{"k4.k5":"e4"}}, {$project:{_id:0,k1:1,k2:2,k3:3,k4:1,kk:"$k4.k5"}}).pretty()
{
    "k1" : "v1",
    "k2" : "v2",
    "k3" : [
        "e1",
        "e2",
        "e3"
    ],
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    },
    "kk" : [
        "e4",
        "e5",
        "e6"
    ]
}

// match as early as possible => match after unwind
> db.unwinddata.aggregate({$match:{"k4.k5":"e4"}}, {$unwind: "$k3"}, {$match:{"k3":"e3"}}, {$project:{_id:0}}).pretty()
{
    "k1" : "v1",
    "k2" : "v2",
    "k3" : "e3",
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    }
}

$filter an array
// prepare data
> db.unwinddata.updateOne({}, {$set:{"k6":[{"kv":{"num":62}},{"kv":{"num":64}}]}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.unwinddata.find().pretty()
{
    "_id" : ObjectId("5f84074ba576e2ec23a7ec0a"),
    "k1" : "v1",
    "k2" : "v2",
    "k3" : [
        "e1",
        "e2",
        "e3"
    ],
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    },
    "k6" : [
        {
            "kv" : {
                "num" : 62
            }
        },
        {
            "kv" : {
                "num" : 64
            }
        }
    ]
}

> db.unwinddata.aggregate({$project:{k6:1,kk:{$filter:{input:"$k6",as:"kvkvkv",cond:{$gte:["$$kvkvkv.kv.num",63]}}}}}).pretty()
{
    "_id" : ObjectId("5f84074ba576e2ec23a7ec0a"),
    "k6" : [
        {
            "kv" : {
                "num" : 62
            }
        },
        {
            "kv" : {
                "num" : 64
            }
        }
    ],
    "kk" : [
        {
            "kv" : {
                "num" : 64
            }
        }
    ]
}

Use $arrayElemAt to select specified index of an array
// $arrayElemAt with -1 select the first value
> db.unwinddata.aggregate({$project:{k1:1,k2:1,k3:1,k4:1,k6:1,kk:{$arrayElemAt:["$k6",-1]}}}).pretty()
{
    "_id" : ObjectId("5f833438651639530e9c2b82"),
    "k1" : "v1",
    "k2" : "v2",
    "k3" : [
        "e1",
        "e2",
        "e3"
    ],
    "k4" : {
        "k5" : [
            "e4",
            "e5",
            "e6"
        ]
    },
    "k6" : [
        {
            "kv" : {
                "num" : 62
            }
        },
        {
            "kv" : {
                "num" : 64
            }
        }
    ],
    "kk" : {
        "kv" : {
            "num" : 64
        }
    }
}

$slice to get range of data.
> db.unwinddata.aggregate({$project:{_id:0,k6:1,kk:{$slice:["$k6.kv.num",1,2]}}}).pretty()
{
    "k6" : [
        {
            "kv" : {
                "num" : 62
            }
        },
        {
            "kv" : {
                "num" : 64
            }
        }
    ],
    "kk" : [
        64
    ]
}

Get array size by $size
> db.unwinddata.aggregate({$project:{_id:0,k6:1,kk:{$size:"$k6"}}}).pretty()
{
    "k6" : [
        {
            "kv" : {
                "num" : 62
            }
        },
        {
            "kv" : {
                "num" : 64
            }
        }
    ],
    "kk" : 2
}


沒有留言:

張貼留言

別名演算法 Alias Method

 題目 每個伺服器支援不同的 TPM (transaction per minute) 當 request 來的時候, 系統需要馬上根據 TPM 的能力隨機找到一個適合的 server. 雖然稱為 "隨機", 但還是需要有 TPM 作為權重. 解法 別名演算法...