【问题标题】:Mongoose query not showing subdocument猫鼬查询不显示子文档
【发布时间】:2019-10-19 12:14:49
【问题描述】:

运行 find() 时,我无法让 mongoose 显示子文档,而它在 mongodb shell 中显示得非常好。

应根据我的架构嵌入子文档,而不是引用 objectId,因此我不应该运行任何黑魔法巫术来显示我的数据。

const UserSchema = new mongoose.Schema({
  username: String;
  xp: Number;
  //etc.
});

const RoomSchema = new mongoose.Schema({
  timestamp: { type: Date, default: Date.now },
  status: { type: String, enum: ["pending", "ongoing", "completed"]},
  players: {
    type: [{
      points: { type: Number, default: 0 },
      position: String,
      user: UserSchema
    }],
    maxlength:2
  }
});

添加新房间后:

let room = new Room(coreObj);
room.players.push({
  points: 0,
  position: 'blue',
  user: userObj //where userObj is a result of running findById on User model
});

它在 mongo shell 中显示得很好,当运行 db.rooms.find({}).pretty() 时,我可以看到已添加完整文档。但是,在猫鼬模型上运行时:

Room.find({}).exec((err,rooms)=>{
  console.log(rooms[0].toJSON()); 
});

我看不到用户子文档,而且我看不到用户字段!似乎是什么问题?

从猫鼬模型记录的 json:

{
    "status": "pending",
    "_id": "5cf5a25c050db208641a2076",
    "timestamp": "2019-06-03T22:42:36.946Z",
    "players": [
        {
            "points": 0,
            "_id": "5cf5a25c050db208641a2077",
            "position": "blue"
        }
    ],
    "__v": 0
}

来自mongo shell的json:

{
        "_id" : ObjectId("5cf5a25c050db208641a2076"),
        "status" : "pending",
        "timestamp" : ISODate("2019-06-03T22:42:36.946Z"),
        "players" : [
                {
                        "points" : 0,
                        "_id" : ObjectId("5cf5a25c050db208641a2077"),
                        "position" : "blue",
                        "user" : {
                                "xp" : 0,
                                "_id" : ObjectId("5cf2da91a45db837b8061270"),
                                "username" : "bogdan_zvonko",
                                "__v" : 0
                        }
                }
        ],
        "__v" : 0
}

【问题讨论】:

  • “看不到用户子文档”到底是什么意思?请将您打印到控制台时看到的内容发布出来。
  • @kevinadi 我相应地更新了问题。有什么想法可以引导我朝着正确的方向前进吗?

标签: mongodb typescript mongoose


【解决方案1】:

我不完全确定您为什么看不到 sub-sub-document,但这个代码示例为我正确打印了它。示例最初发布在https://mongoosejs.com/docs/subdocs.html,但稍作修改以包含子子文档,因此它看起来与您的代码相似:

var grandChildSchema = new mongoose.Schema({ name: 'string' });

var childSchema = new mongoose.Schema({ name: 'string', grandChild: grandChildSchema });

var parentSchema = new mongoose.Schema({ children: [childSchema] });

var Parent = mongoose.model('Parent', parentSchema);

var parent = new Parent({
  children: [
    { name: 'Matt', grandChild: {name: 'Matt Jr'} },
    { name: 'Sarah', grandChild: {name: 'Sarah Jr'} }
  ]
})

parent.save(function() {
  Parent.find().exec(function(err, res) {
    console.log(JSON.stringify(res[0]))
    mongoose.connection.close()
  })
});

执行此代码导致:

{
  "_id": "5cf7096408b1f54151ef907c",
  "children": [
    {
      "_id": "5cf7096408b1f54151ef907f",
      "name": "Matt",
      "grandChild": {
        "_id": "5cf7096408b1f54151ef9080",
        "name": "Matt Jr"
      }
    },
    {
      "_id": "5cf7096408b1f54151ef907d",
      "name": "Sarah",
      "grandChild": {
        "_id": "5cf7096408b1f54151ef907e",
        "name": "Sarah Jr"
      }
    }
  ],
  "__v": 0
}

这是使用 Mongoose 5.5.12 测试的。

请注意,我使用 JSON.stringify() 打印文档,而不是使用 Mongoose 的 toJSON()

【讨论】:

    【解决方案2】:

    牢记最佳实践,我认为在RoomSchema 中引用UserSchema 会更合适。比如:

    ...
    user: {
       type: Schema.Types.ObjectId,
       ref: 'UserSchema'
    }
    

    然后您将在该字段中存储user._id

    这样,如果用户被修改,您的RoomSchema 始终引用正确的信息。然后,您可以使用 Mongoose 的 populate

    获取用户

    【讨论】:

    • 感谢您的建议,可能会像这样编辑它。由于房间只是临时的,我认为嵌入文档会更容易,因为它会使查询更容易(更快?)你知道为什么会发生这种奇怪的行为吗,同一个查询如何在 mongoose 和 mongodb 中给出不同的结果壳?
    猜你喜欢
    • 2015-06-26
    • 2017-06-01
    • 2014-03-21
    • 1970-01-01
    • 2013-10-21
    • 2013-04-16
    • 2013-08-24
    • 2017-12-05
    • 1970-01-01
    相关资源
    最近更新 更多