如何使用mongo聚合在子登记中查找数据?

发布于 01-21 04:46 字数 1335 浏览 2 评论 0原文

我想从另一个集合中的子图中$查找数据。我有调查答案,我想按问题类别的姓名进行分组。

调查文档如下所示:

{
  _id: new ObjectId("62555be60401f0a21553da9a"),
  name: 'new survey',
  questions: [
    {
      text: 'question 1',
      category_id: new ObjectId("62555be60401f0a21553da99"),
      options: [Array],
      _id: new ObjectId("62555be60401f0a21553da9c"),
    },
    ...
}

类别集合只是名称,_id:

{
   _id: new ObjectId("62555be60401r0a27553da99"),
   name: "category name"
}

我有这样的答案数据:

[
  {
    answers: {
      k: '62555be60401f0a21553da9c',
      v: new ObjectId("62555880da8fb89651f6a292")
    },
  },
  {
    answers: {
      k: '62555880da8fb89651f6a29b',
      v: new ObjectId("62555880da8fb89651f6a29e")
    },
  }
  ...
]

k是一个符合中的_id的字符串。 susemy.questions数组。

我想获得这样的数据:

[
  {
    answers: {
      k: 'question 1',
      v: new ObjectId("62555880da8fb89651f6a292")
    },
    category: 'category name'
  },
  {
    answers: {
      k: 'question 2',
      v: new ObjectId("62555880da8fb89651f6a29e")
    },
    category: 'other category name'
  }
  ...
]

任何帮助都将不胜感激!

我想我可能可以找出类别部分,但是我无法弄清楚如何使用$ lookup从子图中获取信息。从文档中,我猜想它可能会在查找中进行一些管道。虽然很困难。

I want to $lookup data from a subdocument in another collection. I have survey answers, and I want to group them by the question category's name.

The survey documents looks like this:

{
  _id: new ObjectId("62555be60401f0a21553da9a"),
  name: 'new survey',
  questions: [
    {
      text: 'question 1',
      category_id: new ObjectId("62555be60401f0a21553da99"),
      options: [Array],
      _id: new ObjectId("62555be60401f0a21553da9c"),
    },
    ...
}

Category collection is just name and _id:

{
   _id: new ObjectId("62555be60401r0a27553da99"),
   name: "category name"
}

I have answer data like this:

[
  {
    answers: {
      k: '62555be60401f0a21553da9c',
      v: new ObjectId("62555880da8fb89651f6a292")
    },
  },
  {
    answers: {
      k: '62555880da8fb89651f6a29b',
      v: new ObjectId("62555880da8fb89651f6a29e")
    },
  }
  ...
]

k is a string that matches to the _id in the survey.questions array.

I'd like to get the resulting data like this:

[
  {
    answers: {
      k: 'question 1',
      v: new ObjectId("62555880da8fb89651f6a292")
    },
    category: 'category name'
  },
  {
    answers: {
      k: 'question 2',
      v: new ObjectId("62555880da8fb89651f6a29e")
    },
    category: 'other category name'
  }
  ...
]

any help would be greatly appreciated!

I think I could probably figure out the category part, but I cannot figure out how to use $lookup to get info from a subdocument. From the docs I'm guessing its maybe some pipeline within a lookup. Pretty stumped though.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

临风闻羌笛 2025-01-28 04:46:02

您可以执行这样的操作,使用管道仅匹配surveys具有worded._idandy> ansy> ansy.k值匹配的值

db.answer.aggregate([
  {
    $lookup: {
      "from": "survey",
      "let": {
        "k": {
          "$toObjectId": "$answers.k"
        }
      },
      pipeline: [
        {
          "$match": {
            "$expr": {"$in": ["$k", "$questions._id"]}
          }
        }
      ],
      as: "details"
    }
  },
  {
    $project: {
      answers: 1,
      details: {"$arrayElemAt": ["$details", 0]}
      }
  },
  {
    $project: {
      answers: 1,
      categoryData: {
        $filter: {
          input: "$details.questions",
          as: "item",
          cond: {$eq: ["$item._id", {"$toObjectId": "$answers.k"}]}
        }
      }
    }
  },
  {
    $project: {
      answers: 1,
      catData: {"$arrayElemAt": ["$categoryData", 0]}
    }
  },
  {
    $lookup: {
      from: "Category",
      localField: "catData.category_id",
      foreignField: "_id",
      as: "cat"
    }
  },
  {
    $project: {
      answers: 1,
      _id: 0,
      category: {"$arrayElemAt": ["$cat", 0]}
    }
  },
  {
    $project: {answers: 1, name: "$category.name"}
  }
])

。请参阅 Playground

也许可以在$ lookup 为了简化查询的其余部分

You can do something like this, using a pipeline to match only surveys that have questions._id that matches the answer.k value

db.answer.aggregate([
  {
    $lookup: {
      "from": "survey",
      "let": {
        "k": {
          "$toObjectId": "$answers.k"
        }
      },
      pipeline: [
        {
          "$match": {
            "$expr": {"$in": ["$k", "$questions._id"]}
          }
        }
      ],
      as: "details"
    }
  },
  {
    $project: {
      answers: 1,
      details: {"$arrayElemAt": ["$details", 0]}
      }
  },
  {
    $project: {
      answers: 1,
      categoryData: {
        $filter: {
          input: "$details.questions",
          as: "item",
          cond: {$eq: ["$item._id", {"$toObjectId": "$answers.k"}]}
        }
      }
    }
  },
  {
    $project: {
      answers: 1,
      catData: {"$arrayElemAt": ["$categoryData", 0]}
    }
  },
  {
    $lookup: {
      from: "Category",
      localField: "catData.category_id",
      foreignField: "_id",
      as: "cat"
    }
  },
  {
    $project: {
      answers: 1,
      _id: 0,
      category: {"$arrayElemAt": ["$cat", 0]}
    }
  },
  {
    $project: {answers: 1, name: "$category.name"}
  }
])

As you can see on the playground

Maybe it is possible to filter the results during the $lookup in order to simplify the rest of the query

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文