2015年12月30日 星期三

mongodb embedded documents query


mongodb embedded documents query example







schema


{
    "_id" : NumberLong(1),
    "_class" : "User",
    "account" : "todd1",
    "friendUserList" : [
        {
            "userId" : NumberLong(2),
            "userAccount" : "todd2",
            "state" : "AGREE"
        },
        {
            "userId" : NumberLong(3),
            "userAccount" : "todd3",
            "state" : "INIT"
        },
        {
            "userId" : NumberLong(5),
            "userAccount" : "todd4",
            "state" : "INIT"
        }
    ]
}

{
    "_id" : NumberLong(2),
    "_class" : "User",
    "account" : "todd2",
    "friendUserList" : [
        {
            "userId" : NumberLong(6),
            "userAccount" : "todd6",
            "state" : "AGREE"
        },
        {
            "userId" : NumberLong(7),
            "userAccount" : "todd7",
            "state" : "INIT"
        }
    ]
}

Query

1.embedded document 只要有符合,整個document
db.user.find({
    friendUserList : {
        $elemMatch : {
            state : 'INIT'
        }
    }
})

但這樣方式,直接這樣寫效果相同
db.user.find( { 'friendUserList.state': 'INIT' } )

2.指定條件與回傳的欄位
db.user.find({ '_id': 1 }, {'account': 1, 'friendUserList': 1});

3. match 先搜尋符合條件,但加總embedded的數量
db.user.aggregate(
    { $match : {'friendUserList.state': 'INIT'}},
    { $project: {'friendUserList': 1 }},
    { $unwind: "$friendUserList" },
    { $group: { _id: "result", count: { $sum: 1 }}}
);

{
    "result" : [ 
        {
            "_id" : "result",
            "count" : 5.0000000000000000
        }
    ],
    "ok" : 1.0000000000000000
}

所以若執行
db.user.aggregate(
    { $match : {'friendUserList.state': 'AGREE'}},
    { $project: {'friendUserList': 1 }},
    { $unwind: "$friendUserList" },
    { $group: { _id: "result", count: { $sum: 1 }}}
);

回傳count 也會是 5

再加個條件 id = 1 來驗證看看
db.user.aggregate(
    { $match : {'friendUserList.state': 'AGREE', '_id': 1}},
    { $project: {'friendUserList': 1 }},
    { $unwind: "$friendUserList" },
    { $group: { _id: "result", count: { $sum: 1 }}}
);

{
    "result" : [ 
        {
            "_id" : "result",
            "count" : 3.0000000000000000
        }
    ],
    "ok" : 1.0000000000000000
}

4.使用mongodb提供的count function

db.user.count( { account: 'todd1' } )
回傳會是1

db.user.count( { 'friendUserList.state': 'AGREE' } )
回傳會是2

但這還是以root document為單位來看

5.只加總 embedded document 符合條件的數量
目前只試出使用aggregate的方式

db.user.aggregate(
    { $match : {'_id': 1}},
    { $project: {'friendUserList': 1 }},
    { $unwind: "$friendUserList" },
    { $match : {'friendUserList.state': 'INIT'}},
    { $group: { _id: "result", count: { $sum: 1 }}}
);
{
    "result" : [ 
        {
            "_id" : "result",
            "count" : 2.0000000000000000
        }
    ],
    "ok" : 1.0000000000000000
}

0 意見: