【问题标题】:Nesting and querying documents with MongoDB使用 MongoDB 嵌套和查询文档
【发布时间】:2016-05-07 21:41:07
【问题描述】:

我有一个或多或少看起来像这样的数据结构:

var city = {
  name: String,
  mayor: Person,
  citizens: [Person]
};

我认为我的用例非常适合使用 MongoDB,但我有几个问题。上面的模型已经用 mongoose 实现了,我使用sub documents 将 Persons 嵌套在 City 中。显然,Citizens 数组可能会变得很长,这就是为什么 MongoDB 似乎是一个不错的选择。

这是构建数据的有效方式吗?我想知道每次我想选择一个城市时,Mongo 是否必须进行某种形式的加入,其中 all 是它的公民(或其中很大一部分)。这显然会破坏使用文档数据库的目的。

另外,当我在 mongo 终端中尝试类似db.cities.find({name:'Berlin'}).mayor 时,我没有得到任何结果。当我尝试db.cities.find({name:'Berlin'}) 时,它会显示城市,并且还会显示市长的对象 ID,但不会显示市长/个人的所有属性。

那么我如何用子文档查询,这是一种很好的工作方式吗?

【问题讨论】:

    标签: node.js mongodb mongoose document-database odm


    【解决方案1】:

    我会推荐您的架构如下Populate。 MongoDB 中没有joins,但有时我们仍然希望引用其他集合中的文档。这就是人口的来源。

    var personSchema = Schema({
      _id     : Number,
      name    : String,
    }); 
    
    var Person = mongoose.model('Person', personSchema);
    
    var citySchema = Schema{
      name: String,
      mayor: { type: Schema.Types.ObjectId, ref: 'Person' },
      citizens: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
    };
    
    var City = mongoose.model('City', citySchema);
    

    通过Berlin查询城市

    City.find({name: 'Berlin'})
        .populate('mayor')
        .populate('citizens')
        .exec(...)
    

    将从数据库中检索mayor 和citizens 相关文档。

    如果您担心城市中的citizens 太多,导致city 与populate 中的city 中的人相比太大,另一种选择是

    var personSchema = Schema({
      _id     : Number,
      name    : String,
      cityId  : { type: Schema.Types.ObjectId, ref: 'City' }
    }); 
    
    var Person = mongoose.model('Person', personSchema);
    
    var citySchema = Schema{
      name: String,
      mayor: { type: Schema.Types.ObjectId, ref: 'Person' }
    };
    
    var City = mongoose.model('City', citySchema);
    

    用aggregation查询城市Berlin,这里是示例代码。

    City.find({name: 'Berlin'})
        .populate('mayor')
        .exec(function(err, city) {
           Person.aggregate([
              {$group: {cityId: city._id, citizens: {$push: '$name'}}}
              // ...
           ], function(err, result) {
              //...
    });
    

    【讨论】:

      猜你喜欢
      • 2021-02-25
      • 2016-08-16
      • 2015-02-10
      • 2012-10-17
      • 2018-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多