【问题标题】:MongoDB - Get a field from all matching objects in an array?MongoDB - 从数组中的所有匹配对象中获取一个字段?
【发布时间】:2020-06-02 18:07:50
【问题描述】:

我一直在将 mySQL 迁移到 mongoDB。 我想嵌入教师,课程表到教师表。 我有一个 mongo 数据库结构如下。

{ 
"_id" : "14365", 
"ID" : "14365", 
"name" : "Lembr", 
"dept_name" : "Accounting", 
"salary" : 32241.56, 
"teaches" : [
    {
        "ID" : "14365", 
        "course_id" : "200", 
        "sec_id" : "1", 
        "semester" : "Spring", 
        "year" : 2007.0, 
        "course" : {
            "course_id" : "200", 
            "title" : "The Music of the Ramones", 
            "dept_name" : "Accounting", 
            "credits" : 4.0
        }
    }, 
    {
        "ID" : "14365", 
        "course_id" : "843", 
        "sec_id" : "1", 
        "semester" : "Fall", 
        "year" : 2010.0, 
        "course" : {
            "course_id" : "843", 
            "title" : "Environmental Law", 
            "dept_name" : "Math", 
            "credits" : 4.0
        }
    }
]

}

我想像下面的 SQL 查询一样查询。

SELECT name, title From instructor Natural join teaches Natural join course;

如何在 mongodb 中查询?

【问题讨论】:

  • 您的预期输出是什么?你想实现什么,你能用语言表达吗?另外,您能否提供一些来自每个集合的示例文档?
  • 我现在想从双重嵌套的课程对象中输出与讲师相同的 dept_name 的课程标题。
  • 请在 OP 中更新相同的内容,并附上示例。而且我要求从每个集合中提供一些示例文档,也在 OP 中更新它。

标签: database mongodb mongodb-query aggregation-framework


【解决方案1】:

你需要MongoDB的聚合算子$reduce

db.collection.aggregate([
  /** Using project stage we'll project only needed fields */
  {
    $project: {
      _id: 0, // _id is by default included - you need to exclude it
      name: 1,
      title: {
        $reduce: {
          input: "$teaches", // Iterate on objects of `teaches` array
          initialValue: [], // Initial value
          in: {
            $cond: [
              { $eq: ["$$this.course.dept_name", "$dept_name"] }, // condition to check
              {
                $concatArrays: ["$$value", ["$$this.course.title"]], // If condition is met push values to array
              },
              "$$value" // If not send same holding array back for this iteration
            ]
          }
        }
      }
    }
  }
]);

测试: mongoplayground

测试: $filter: mongoplayground

注意:

我们使用$reduce 将来自teaches 数组中不同对象的所有标题带到一个数组中。你也可以使用$filter 来实现类似的东西。如果在任何情况下,如果您的title 只是数组中的一个元素(teaches 数组中没有重复的dept_name),那么您可以使用$unwind$arrayElemAttitle 数组转换为字符串。

【讨论】:

  • 我可以问更多问题吗?我怎样才能摆脱这里的空标题数组?
  • @jieun:title 上的空白意味着该文档没有找到匹配项 - 这就是为什么 $filter 会导致 [] !你想要那个没有title字段的文档,还是你根本不需要那个文档(比如完全删除title : []的文档)?
  • 我想我完全需要那个文档(比如完全删除标题:[] 的文档)。
  • @jieun :好的,因为您不需要该文档,那么您需要添加$match 作为第一阶段{ $match: { $expr: { $in: [ "$dept_name", "$teaches.course.dept_name" ] } } }测试: mongoplayground.net/p/cqXf3VTZnwB ,它将仅获取 teaches 数组中至少一个对象与 dept_name 匹配的文档。
  • 感激不尽!!!!太感谢了。多亏了你,我解决了所有问题!
猜你喜欢
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 2017-09-13
  • 2020-04-04
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
相关资源
最近更新 更多