展开只是如果嵌入式存在
unwind just if embedded exist
我有高度嵌套的 mongodb 对象集,所以我的集合是:
{
"_id":17846384es,
"company_name":"company1",
"company_location":"city1",
"phone":"xxxxx",
"open_time":"xxx",
"products":[
{
"product_id":"123785",
"product_name":"product1",
"user_votes":[
{
"user_id":1,
"vote":1
},
{
"user_id":2,
"vote":2
}
]
},
{
"product_id":"98765",
"product_name":"product2",
"user_votes":[
{
"user_id":5,
"vote":3
},
{
"user_id":3,
"vote":3
}
]
}
]
}
我对这个子文档使用了一些操作,比如排序和求和,所以我使用了
db.products.aggregate([
{ $unwind: "$products" },
{ $project: {
company_name: 1,
products: {
product_id: 1,
product_name: 1,
user_votes: 1,
votes: { $sum: "$products.user_votes.vote" }
}
} },
{ $sort: { totalVotes: -1 } },
{
$group: {
_id: "$_id",
company_name: { $first: "$company_name" },
products: { $push: "$products" }
}
}
])
得到这个结果:
{
"_id":17846384es,
"company_name":"company1",
"products":[
{
"product_id":"98765",
"product_name":"product2",
"user_votes":[
{
"user_id":5,
"vote":3
},
{
"user_id":3,
"vote":3
}
]
"votes":6
},
{
"product_id":"123785",
"product_name":"product1",
"user_votes":[
{
"user_id":1,
"vote":1
},
{
"user_id":2,
"vote":2
}
],
"votes":3
}
]
}
但是如果产品文档不存在,我得到的结果是空的。即使产品文档不存在,我也想获得包含公司信息的结果。
首先,您可以使用"preserveNullAndEmptyArrays"
保留没有产品数组的公司。
下面的查询应该输出公司名称,即使它没有产品数组。
我认为您正在尝试对投票进行求和并对产品数组进行排序,以获得最多的产品作为数组中的第一个元素。下面的查询应该会产生结果。
db.product.aggregate([
{ $unwind: { path : "$products", preserveNullAndEmptyArrays : true }},
{ $project: {
company_name: 1,
products : { $ifNull : ["$products", "0"]}}
},
{ $project: {
company_name: 1,
products: {
product_id: 1,
product_name: 1,
user_votes: 1,
votes: { $sum: "$products.user_votes.vote" }
}
} },
{ $sort: { "products.votes": -1 } },
{
$group: {
_id: "$_id",
company_name: { $first: "$company_name" },
products: { $push: "$products" }
}
},
]);
如果你想保留最后没有产品的公司。您可以将此附加排序添加为上述查询中的最后一个管道。
{ $sort: { "products.votes": -1 } },
没有产品数组的公司输出如下:-
{
"_id" : ObjectId("57f2bd50dd4752c20947fd03"),
"company_name" : "company2",
"products" : [
{
"votes" : 0
}
]
}
我有高度嵌套的 mongodb 对象集,所以我的集合是:
{
"_id":17846384es,
"company_name":"company1",
"company_location":"city1",
"phone":"xxxxx",
"open_time":"xxx",
"products":[
{
"product_id":"123785",
"product_name":"product1",
"user_votes":[
{
"user_id":1,
"vote":1
},
{
"user_id":2,
"vote":2
}
]
},
{
"product_id":"98765",
"product_name":"product2",
"user_votes":[
{
"user_id":5,
"vote":3
},
{
"user_id":3,
"vote":3
}
]
}
]
}
我对这个子文档使用了一些操作,比如排序和求和,所以我使用了
db.products.aggregate([
{ $unwind: "$products" },
{ $project: {
company_name: 1,
products: {
product_id: 1,
product_name: 1,
user_votes: 1,
votes: { $sum: "$products.user_votes.vote" }
}
} },
{ $sort: { totalVotes: -1 } },
{
$group: {
_id: "$_id",
company_name: { $first: "$company_name" },
products: { $push: "$products" }
}
}
])
得到这个结果:
{
"_id":17846384es,
"company_name":"company1",
"products":[
{
"product_id":"98765",
"product_name":"product2",
"user_votes":[
{
"user_id":5,
"vote":3
},
{
"user_id":3,
"vote":3
}
]
"votes":6
},
{
"product_id":"123785",
"product_name":"product1",
"user_votes":[
{
"user_id":1,
"vote":1
},
{
"user_id":2,
"vote":2
}
],
"votes":3
}
]
}
但是如果产品文档不存在,我得到的结果是空的。即使产品文档不存在,我也想获得包含公司信息的结果。
首先,您可以使用"preserveNullAndEmptyArrays"
保留没有产品数组的公司。
下面的查询应该输出公司名称,即使它没有产品数组。
我认为您正在尝试对投票进行求和并对产品数组进行排序,以获得最多的产品作为数组中的第一个元素。下面的查询应该会产生结果。
db.product.aggregate([
{ $unwind: { path : "$products", preserveNullAndEmptyArrays : true }},
{ $project: {
company_name: 1,
products : { $ifNull : ["$products", "0"]}}
},
{ $project: {
company_name: 1,
products: {
product_id: 1,
product_name: 1,
user_votes: 1,
votes: { $sum: "$products.user_votes.vote" }
}
} },
{ $sort: { "products.votes": -1 } },
{
$group: {
_id: "$_id",
company_name: { $first: "$company_name" },
products: { $push: "$products" }
}
},
]);
如果你想保留最后没有产品的公司。您可以将此附加排序添加为上述查询中的最后一个管道。
{ $sort: { "products.votes": -1 } },
没有产品数组的公司输出如下:-
{
"_id" : ObjectId("57f2bd50dd4752c20947fd03"),
"company_name" : "company2",
"products" : [
{
"votes" : 0
}
]
}