如何获取现有文档或新添加的文档

时间:2017-01-24 23:51:38

标签: mongodb mongodb-query

我有一个表结构,如下所示。

{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6b8"), 
 "product" : "product1", 
"title" : "Alt Summit 1", 
"category" : "category1", 
"order" : 1
}
{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6b9"), 
"product" : "product2", 
"title" : "Alt Summit 2", 
"category" : "category1", 
"order" : 2
}
    { 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6ba"), 
 "product" : "product1", 
"title" : "Alt Summit 1", 
"category" : "category1", 
"order" : 2,
"added_by" : user1
}
{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6bb"), 
"product" : "product2", 
"title" : "Alt Summit 2", 
"category" : "category1", 
"order" : 1,
"added_by" : user1
}
{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6bc"), 
"product" : "product3", 
"title" : "Alt Summit 3", 
"category" : "category1", 
"order" : 3,
"added_by" : user1
}
{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6bd"), 
"product" : "product4", 
"title" : "Alt Summit 4", 
"category" : "category1", 
"order" : 4
}

我想首先解释数据库结构。

我的网站上的每个用户都有默认产品,用户可以将自己的产品添加到列表中,也可以重新订购现有列表。当他们添加新产品时,它将通过用户名添加。当他们重新订购产品时,我会通过附加用户名并更改订单来获取现有的默认记录并插入(如果您观察到上述数据,您将会理解)。

现在,我如何获取特定于用户的类别的产品。

例如,如果我需要获取category1中user1的所有产品,则输出应如下所示(根据订单字段排序)。如果仔细观察上述数据,则会使用名为added_by的额外字段重复相同的产品并更改订单。如果用户自定义,我想获得用户的订单,如果不是默认订单。

{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6bb"), 
"product" : "product2", 
"title" : "Alt Summit 2", 
"category" : "category1", 
"order" : 1,
"added_by" : user1
}
{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6ba"), 
 "product" : "product1", 
"title" : "Alt Summit 1", 
"category" : "category1", 
"order" : 2,
"added_by" : user1
}
{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6bc"), 
"product" : "product3", 
"title" : "Alt Summit 3", 
"category" : "category1", 
"order" : 3,
"added_by" : user1
}
{ 
"_id" : ObjectId("5870f1d9dd0ef6e62102e6bd"), 
"product" : "product4", 
"title" : "Alt Summit 4", 
"category" : "category1", 
"order" : 4
}

如果我应该改变表的结构,我愿意接受任何建议。但是在任何时候我都应该能够得到我上面提到的输出。

1 个答案:

答案 0 :(得分:1)

您可以使用当前的Mongo 3.4版本尝试以下聚合。

查询条件的

$match个文档。

$group上的{p> product个文档,并根据较早的排序顺序选择$first,同时将文档保留为$$ROOT

$replaceRootroot文档提升到最高级别。

' $排序' order字段。

db.collection.aggregate([{
    $match: {
    "category": "category1",
        $or: [{
            "added_by": "user1"
        }, {
            "added_by": {
                "$exists": false
            }
        }]
    }
}, {
    $group: {
        "_id": "$product",
        "root": {
            "$first": "$$ROOT"
        }
    }
}, {
    $replaceRoot: {
        newRoot: "$root"
    }
},{
    $sort: {
        "order": 1
    }
}])

OP评论后更新

<{1}}和$group product所有带有$push的产品的

$$ROOT个文档。

$project阶段将$size(如果不是$eq)与1然后$filter进行比较,以选择带有added_by字段的产品。

db.collection.aggregate([{
    $match: {
        "category": "category1",
        $or: [{
            "added_by": "user1"
        }, {
            "added_by": {
                "$exists": false
            }
        }]
    }
}, {
    $group: {
        "_id": "$product",
        "products": {
            "$push": "$$ROOT"
        }
    }
}, {
    $project: {
        "_id": 0,
        "product": {
            "$arrayElemAt": [{
                    "$cond": [
                        {
                            $eq: [{$size: "$products"}, 1]
                        },
                        "$products", 
                        {
                            "$filter": {
                                input: "$products",
                                as: "product",
                                cond: {
                                    $ifNull: ["$$product.added_by", false]
                                }
                            }
                        }
                    ]
                },
                0
            ]
        }
    }
}, {
    $replaceRoot: {
        newRoot: "$product"
    }
}, {
    $sort: {
        "order": 1
    }
}]);