1

假设我们有如下文件:

{ "_id" : 1, "stock_item" : "almonds", warehouse: "B", "instock" : 120 },
{ "_id" : 2, "stock_item" : "pecans", warehouse: "A", "instock" : 80 },
{ "_id" : 3, "stock_item" : "almonds", warehouse: "B", "instock" : 60 },
{ "_id" : 4, "stock_item" : "cookies", warehouse: "B", "instock" : 40 },
{ "_id" : 5, "stock_item" : "cookies", warehouse: "A", "instock" : 80 }

输入是{stock_item: "almonds"}但我们想要:

  1. 查找所有具有 {stock_item: "almonds"} 的文档
  2. 检索第 1 部分返回的所有文档的仓库字段
  3. 返回其仓库字段包含在第 2 部分中的所有文档作为最终结果

所以最终结果将如下所示,因为文档 1 和 3 具有{stock_item: "almonds"}条件并且它们都具有{warehouse: "B"}所以结果我们想要返回所有具有{warehouse: "B “}

{ "_id" : 1, "stock_item" : "almonds", warehouse: "B", "instock" : 120 },
{ "_id" : 3, "stock_item" : "almonds", warehouse: "B", "instock" : 60 },
{ "_id" : 4, "stock_item" : "cookies", warehouse: "B", "instock" : 40 }

我可以分别使用两个查找查询来做到这一点,但我想知道如何在一个查询中使用 mongodb 聚合来做到这一点?

4

2 回答 2

1

当然,两个查询似乎是最直接的方式,这就是我推荐的方式。另一方面,这个问题很有趣,所以通过实验你可以使用$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"
        }
    }
])

蒙戈游乐场

于 2020-10-17T09:33:56.297 回答
0

您需要的是“选择(2)中的选择(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"
    }
  }
])

您可以在此处测试解决方案

于 2020-10-17T10:57:08.313 回答