我有一个表结构,如下所示。
{
"_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
}
如果我应该改变表的结构,我愿意接受任何建议。但是在任何时候我都应该能够得到我上面提到的输出。
答案 0 :(得分:1)
您可以使用当前的Mongo 3.4版本尝试以下聚合。
查询条件的 $match
个文档。
$group
上的{p> product
个文档,并根据较早的排序顺序选择$first
,同时将文档保留为$$ROOT
。
$replaceRoot
将root
文档提升到最高级别。
' $排序' 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
}
}]);