【问题标题】:MongoDB - query with two collectionsMongoDB - 使用两个集合进行查询
【发布时间】:2016-02-21 07:43:06
【问题描述】:

我正在尝试使用 MongoDB,并且一直在尝试对单个集合进行一些基本查询,但我想通过以某种方式链接它们来在我的查询中使用两个集合。我有以下包含电影信息的文件,

电影:

{
      id:  1, 
      title: "abc", 
      release_data: "xxxx",
      IMDBURL: "qwe", 
      genre: ["xx","yy's","zz"]
}

以及另一个集合中的以下类型的文档,其中包含有关用户的信息以及包含他已评分的电影以及评分本身的嵌入式文档。

用户:

{
      id:  1, 
      age: xx, 
      gender: "Y", 
      occupation: "abc", 
      zip_code: "asd", 
      movies:[
      { movie: 1, rating: 5 } , 
      { movie: 2, rating: 3 }, 
      { movie: 3, rating: 4 }, 
      { movie: 4, rating: 3 }
      ]
}

如何进行查询以返回至少一次被评为 5 的电影的标题?谢谢。

【问题讨论】:

标签: mongodb


【解决方案1】:

MongoDB:没有 JOINS,没有事务

很有趣,我从来不需要它们中的任何一个。与您的示例一样,您基本上必须问自己需要回答什么并对数据进行相应建模

  • 哪些电影至少被评为五次?
  • 这些电影叫什么名字?

鉴于您的数据模型,您甚至无法摆脱普通查询:您需要一个聚合。使用以下数据集:

{ "_id" : ObjectId("56c8e58ee99e5c4e87ec3a4e"), "age" : 22, "gender" : "Y", "occupation" : "abc", "zip_code" : "asd", "movies" : [ { "movie" : 1, "rating" : 5 }, { "movie" : 2, "rating" : 3 }, { "movie" : 3, "rating" : 4 }, { "movie" : 4, "rating" : 3 } ] }
{ "_id" : ObjectId("56c8e598e99e5c4e87ec3a4f"), "age" : 22, "gender" : "Y", "occupation" : "abc", "zip_code" : "asd", "movies" : [ { "movie" : 1, "rating" : 5 }, { "movie" : 2, "rating" : 3 }, { "movie" : 3, "rating" : 4 } ] }
{ "_id" : ObjectId("56c8e599e99e5c4e87ec3a50"), "age" : 22, "gender" : "Y", "occupation" : "abc", "zip_code" : "asd", "movies" : [ { "movie" : 1, "rating" : 5 }, { "movie" : 2, "rating" : 3 }, { "movie" : 3, "rating" : 4 } ] }
{ "_id" : ObjectId("56c8e59ae99e5c4e87ec3a51"), "age" : 22, "gender" : "Y", "occupation" : "abc", "zip_code" : "asd", "movies" : [ { "movie" : 1, "rating" : 5 }, { "movie" : 2, "rating" : 3 }, { "movie" : 3, "rating" : 4 } ] }
{ "_id" : ObjectId("56c8e59be99e5c4e87ec3a52"), "age" : 22, "gender" : "Y", "occupation" : "abc", "zip_code" : "asd", "movies" : [ { "movie" : 1, "rating" : 5 }, { "movie" : 2, "rating" : 3 }, { "movie" : 3, "rating" : 4 } ] }

您可以通过以下聚合找到符合您条件的电影

db.movies.aggregate([
  { $unwind:"$movies"},
  { $group:{ _id:"$movies.movie", ratings:{ $sum:1 }}},
  { $match:{ ratings:{ $gte:5}}},
  { $project:{ _id:1 }}
])

这将返回看起来像这样的文档

{ "_id" : 3 }
{ "_id" : 2 }
{ "_id" : 1 }

匹配上面的示例数据。现在,有了这些,您可以在相应的集合中查找电影名称。

聚合,剖析

db.movies.aggregate([

])

要查看单个阶段的作用,只需删除它后面的阶段。

【讨论】:

  • 非常感谢您的详尽回答。我希望将从聚合中获得的数据存储在 var movieIds 中。这样我就可以用 movieIds.length() 遍历它,并将 id 值与电影集合进行比较。但是movieIds 不会像find() 的产物那样具有length() 方法。为了保持一致,您在上面发布的聚合发生在 db.users 而不是 db.movi​​es 中。
  • 好吧,我的收藏被称为 db.movi​​es ;) 而且很明显,我不明白你的用例。当您可以使用 $out 阶段将某些内容存储在专用集合中并正确回答一个答案时,为什么还要将其存储在文档中?
猜你喜欢
  • 2020-03-24
  • 2016-09-27
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2020-11-17
  • 2016-12-13
相关资源
最近更新 更多