如何解决Mongodb聚合在一个阶段中检索字段并在另一个阶段中使用它
假设我们有如下文件:
{ "_id" : 1,"stock_item" : "almonds",warehouse: "B","instock" : 120 },{ "_id" : 2,"stock_item" : "pecans",warehouse: "A","instock" : 80 },{ "_id" : 3,"instock" : 60 },{ "_id" : 4,"stock_item" : "cookies","instock" : 40 },{ "_id" : 5,"instock" : 80 }
输入的是 {stock_item:“杏仁”} ,但我们要:
- 查找所有具有{stock_item:“杏仁”}}的文档
- 检索第1部分中返回的所有文档的仓库字段
- 返回其仓库字段包含在第2部分中的所有单据作为最终结果
所以最终结果将如下所示,因为文档1和3具有 {stock_item:“杏仁”} 条件,并且它们都具有 {仓库:“ B”} >,因此我们想返回所有具有 {warehouse:“ B”} :
的文档{ "_id" : 1,"instock" : 40 }
我可以分别使用两个查找查询来执行此操作,但是我想知道如何在一个查询中使用mongodb聚合来执行此操作?
解决方法
当然,两个查询似乎是最直接的方法,这就是我的建议。另一方面,这个问题很有趣,因此通过实验,您可以使用$lookup来实现所需的目标。
这个想法是,您可以获取一个符合文件过滤条件的文档,然后运行自查找功能,让其余文档知道该文档的内容。
您还需要$unwind和$replaceRoot来调整输出的形状(查找将返回嵌套的子文档数组)。
db.collection.aggregate([
{
$match: { stock_item: "almonds" }
},{
$limit: 1
},{
$lookup: {
from: "collection",let: { si: "$stock_item",w: "$warehouse" },pipeline: [
{ $match: { $expr: { $or: [ { $eq: [ "$$si","$stock_item" ] },{ $eq: [ "$$w","$warehouse" ] } ] } } }
],as: "documents"
}
},{
$unwind: "$documents"
},{
$replaceRoot: {
newRoot: "$documents"
}
}
])
,
您需要的是“ select(2)中的select(1)”。
使用$facet首先找到您的select(2)值,然后在$ in条件下使用它(将与多个仓库一起用作select(2)的结果)
db.collection.aggregate([
{
$facet: {
inCond: [
{
$group: {
_id: "$stock_item",warehouses: {
"$addToSet": "$warehouse"
}
}
},{
$match: {
_id: "almonds"
}
}
],docs: []
}
},{
"$project": {
"docs": {
"$filter": {
"input": "$docs","as": "doc","cond": {
"$in": [
"$$doc.warehouse",{
"$arrayElemAt": [
"$inCond.warehouses",0
]
}
]
}
}
},}
},{
$unwind: "$docs"
},{
"$replaceRoot": {
"newRoot": "$docs"
}
}
])
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。