Mongodb组合聚合查询
我在MongoDB有以下收藏 配置文件集合Mongodb组合聚合查询,mongodb,mongodb-query,Mongodb,Mongodb Query,我在MongoDB有以下收藏 配置文件集合 > db.Profile.find() { "_id" : ObjectId("5ec62ccb8897af3841a46d46"), "u" : "Test User", "is_del": false } > db.Store.find() { "_id" : ObjectId("5eaa939aa709c
> db.Profile.find()
{ "_id" : ObjectId("5ec62ccb8897af3841a46d46"), "u" : "Test User", "is_del": false }
> db.Store.find()
{ "_id" : ObjectId("5eaa939aa709c30ff4703ffd"), "id" : "5ec62ccb8897af3841a46d46", "a" : { "ci": "Test City", "st": "Test State" }, "ip" : false }, "op" : [ ], "b" : [ "normal" ], "is_del": false}
> db.Item.find()
{ "_id" : ObjectId("5ea98a25f1246b53a46b9e10"), "sid" : "5eaa939aa709c30ff4703ffd", "n" : "sample", "is_del": false}
商店收藏
> db.Profile.find()
{ "_id" : ObjectId("5ec62ccb8897af3841a46d46"), "u" : "Test User", "is_del": false }
> db.Store.find()
{ "_id" : ObjectId("5eaa939aa709c30ff4703ffd"), "id" : "5ec62ccb8897af3841a46d46", "a" : { "ci": "Test City", "st": "Test State" }, "ip" : false }, "op" : [ ], "b" : [ "normal" ], "is_del": false}
> db.Item.find()
{ "_id" : ObjectId("5ea98a25f1246b53a46b9e10"), "sid" : "5eaa939aa709c30ff4703ffd", "n" : "sample", "is_del": false}
项目集合
> db.Profile.find()
{ "_id" : ObjectId("5ec62ccb8897af3841a46d46"), "u" : "Test User", "is_del": false }
> db.Store.find()
{ "_id" : ObjectId("5eaa939aa709c30ff4703ffd"), "id" : "5ec62ccb8897af3841a46d46", "a" : { "ci": "Test City", "st": "Test State" }, "ip" : false }, "op" : [ ], "b" : [ "normal" ], "is_del": false}
> db.Item.find()
{ "_id" : ObjectId("5ea98a25f1246b53a46b9e10"), "sid" : "5eaa939aa709c30ff4703ffd", "n" : "sample", "is_del": false}
这些集合之间的关系定义如下:
db.Item.aggregate({$group: {_id: "$sid", count:{$sum:1}}})
db.Profile.aggregate([{ "$addFields": { "pid": { "$toString": "$_id" }}}, { "$lookup": {"from": "Store","localField": "pid","foreignField": "id", "as": "stores"}}])
Profile->Store
:它是1:n
关系<Store
中的code>id字段与配置文件中的id
字段相关
存储
->项
:它也是1:n
关系<项目
中的code>sid字段与存储
中的\u id
字段相关项的计数。必须排除为del
且为true
的文档
我正在尝试以下方法:
查询1以查找每个商店的商品计数
查询2以查找每个配置文件的存储
然后在应用程序逻辑中使用这两个结果来生成组合输出
我的问题1如下:
db.Item.aggregate({$group: {_id: "$sid", count:{$sum:1}}})
db.Profile.aggregate([{ "$addFields": { "pid": { "$toString": "$_id" }}}, { "$lookup": {"from": "Store","localField": "pid","foreignField": "id", "as": "stores"}}])
问题2如下:
db.Item.aggregate({$group: {_id: "$sid", count:{$sum:1}}})
db.Profile.aggregate([{ "$addFields": { "pid": { "$toString": "$_id" }}}, { "$lookup": {"from": "Store","localField": "pid","foreignField": "id", "as": "stores"}}])
在查询中,is\u del
也丢失。有没有更简单的方法在一个查询中执行所有这些操作?如果是这样,可伸缩性会有什么影响?您可以使用MongoDB v3.6中提供的不相关子查询
db.Profile.aggregate([
{
$match: { is_del: false }
},
{
$lookup: {
from: "Store",
as: "stores",
let: {
pid: { $toString: "$_id" }
},
pipeline: [
{
$match: {
is_del: false,
$expr: { $eq: ["$$pid", "$id"] }
}
},
{
$lookup: {
from: "Item",
as: "items",
let: {
sid: { $toString: "$_id" }
},
pipeline: [
{
$match: {
is_del: false,
$expr: { $eq: ["$$sid", "$sid"] }
}
},
{
$count: "count"
}
]
}
},
{
$unwind: "$items"
}
]
}
}
])
为了提高性能,我建议您将引用ID存储为ObjectId
,这样您就不必在每一步都转换它们。存储集合中文档的结构有点奇怪,是否应该在“ip”之后有一个结束的花括号:false
?为什么不发布一些所有收集的样本数据?@thammada.ts感谢您指出。我想阿什纠正了这个问题。@varman:样本数据就在那里。如果你需要更多信息,请告诉我。