我已将我的第一步移至MongoDB,但我在编写复杂查询时遇到了困难。
我的收藏中有几个这样的项目:
{ "_id" : "sku001", "deposits" : [ { "deposit_id" : "deposit01", "total" : "3", "sizes" : [ { "size" : "36", "stock" : "2" }, { "size" : "38", "stock" : "0" }, { "size" : "40", "stock" : "0" }, { "size" : "42", "stock" : "0" }, { "size" : "44", "stock" : "0" }, { "size" : "46", "stock" : "1" }, { "size" : "48", "stock" : "0" }, { "size" : "50", "stock" : "0" }, { "size" : "52", "stock" : "0" } ] }, { "deposit_id" : "deposit02", "total" : "5", "sizes" : [ { "size" : "36", "stock" : "1" }, { "size" : "38", "stock" : "1" }, { "size" : "40", "stock" : "0" }, { "size" : "42", "stock" : "1" }, { "size" : "44", "stock" : "0" }, { "size" : "46", "stock" : "1" }, { "size" : "48", "stock" : "1" }, { "size" : "50", "stock" : "0" }, { "size" : "52", "stock" : "0" } ] }, { "deposit_id" : "deposit03", "total" : "2", "sizes" : [ { "size" : "36", "stock" : "1" }, { "size" : "38", "stock" : "0" }, { "size" : "40", "stock" : "0" }, { "size" : "42", "stock" : "1" }, { "size" : "44", "stock" : "0" }, { "size" : "46", "stock" : "0" }, { "size" : "48", "stock" : "0" }, { "size" : "50", "stock" : "0" }, { "size" : "52", "stock" : "0" } ] }, { "deposit_id" : "deposit04", "total" : "0", "sizes" : [ { "size" : "36", "stock" : "0" }, { "size" : "38", "stock" : "0" }, { "size" : "40", "stock" : "0" }, { "size" : "42", "stock" : "0" }, { "size" : "44", "stock" : "0" }, { "size" : "46", "stock" : "0" }, { "size" : "48", "stock" : "0" }, { "size" : "50", "stock" : "0" }, { "size" : "52", "stock" : "0" } ] } ] }
并且想编写一个查询来输出这个结果文档:
{ "_id" : "sku001", "total": 10, "sizes" [ { "size" : "36", "stock" : "4" }, { "size" : "38", "stock" : "1" }, { "size" : "40", "stock" : "0" }, { "size" : "42", "stock" : "2" }, { "size" : "44", "stock" : "0" }, { "size" : "46", "stock" : "2" }, { "size" : "48", "stock" : "1" }, { "size" : "50", "stock" : "0" }, { "size" : "52", "stock" : "0" } ] }
这样:
我知道我需要将ObjectMapper mapper = new ObjectMapper();
Foo response = mapper.readValue("{\"some_key\": {\"a\": 1, \"b\": \"text\"}}", Foo.class);
与aggregate()
,$unwind
和$group
一起使用,但我不了解如何以及以何种顺序。< / p>
你能帮帮我吗?我使用MongoDB版本3.4.3
答案 0 :(得分:0)
在将聚合框架中的运算符应用于生成所需报告之前,您可能希望先更改架构,即需要将字符串值解析为数字,然后运行聚合操作。
要更改架构,您需要迭代集合,并为集合中的每个文档更新需要将字符串值解析为数字的键。如果无法更改原始集合架构,您可能希望使用更新的架构创建临时集合。 对于前者,请考虑运行以下更新操作(对于相对较小的集合):
db.collection.find({}).snapshot()
.forEach(function(doc) {
var query = { "_id": doc._id },
update = { "$set": {} };
for (var i=0; i<doc.deposits.length; i++) {
update["$set"]["deposits."+i+".total"] = parseInt(doc.deposits[i].total);
for (var j=0; j<doc.deposits[i].sizes.length; j++) {
update["$set"]["deposits."+i+".sizes."+j+".stock"] = parseInt(doc.deposits[i].sizes[j].stock);
}
}
printjson(query);
printjson(update);
db.collection.updateOne( query, update );
});
拥有正确的架构将允许您在以下聚合操作中运行管道,该操作应该为您提供所需的报告:
db.collection.aggregate([
{ "$unwind": "$deposits" },
{ "$unwind": "$deposits.sizes" },
{
"$group": {
"_id": {
"id": "$_id",
"size": "$deposits.sizes.size"
},
"total_stock": { "$sum": "$deposits.sizes.stock" },
"deposits": {
"$push": {
"deposit_id": "$deposits.deposit_id",
"total": "$deposits.total"
}
}
}
},
{ "$unwind": "$deposits" },
{
"$group": {
"_id": {
"id": "$_id.id",
"deposit_id": "$deposits.deposit_id"
},
"sizes": {
"$push": {
"size": "$_id.size",
"stock": "$total_stock"
}
},
"total": { "$first": "$deposits.total" }
}
},
{
"$group": {
"_id": "$_id.id",
"total": { "$sum": "$total" },
"sizes": { "$first": "$sizes" }
}
}
])