在MongoDB中处理嵌入文档引用的推荐方法是什么?

在MongoDB中处理嵌入文档引用的推荐方法是什么?,mongodb,reference,Mongodb,Reference,我是MongoDB的新手。我的问题是:一个用户可以有多个化身,但只有一个是活动的。以下是目前用户文档的外观: { "_id": ObjectId("515c99f7e4d8094a87e13757"), "avatars": [{ "url": "http://example.com/img/photo1.jpg", "width": 50, "height": 50, }, { "active": true, "url": "http://e

我是MongoDB的新手。我的问题是:一个用户可以有多个化身,但只有一个是活动的。以下是目前用户文档的外观:

{
  "_id": ObjectId("515c99f7e4d8094a87e13757"),
  "avatars": [{
    "url": "http://example.com/img/photo1.jpg",
    "width": 50,
    "height": 50,
  }, {
    "active": true,
    "url": "http://example.com/img/photo2.jpg",
    "width": 50,
    "height": 50,
  }]
}
这个解决方案很简单,但有几件事我不喜欢:

  • 更改活动化身意味着更新两个嵌入文档
  • 我不确定它在并发访问的情况下是否会表现良好(读_avatar+更改_active_avatar或更改_active+更改_active)(会吗?)
  • 寻找活动的化身需要顺序搜索
  • 另一个解决办法是:

    {
      "_id": ObjectId("515c99f7e4d8094a87e13757"),
      "active_avatar_id": 2,
      "avatars": [{
        "_id": 1,
        "url": "http://example.com/img/photo1.jpg",
        "width": 50,
        "height": 50,
      }, {
        "_id": 2,
        "url": "http://example.com/img/photo2.jpg",
        "width": 50,
        "height": 50,
      }]
    }
    
    {
      "_id": ObjectId("515c99f7e4d8094a87e13757"),
      "active_avatar": {
        "url": "http://example.com/img/photo2.jpg",
        "width": 50,
        "height": 50,
      },
      "extra_avatars": [{
        "url": "http://example.com/img/photo1.jpg",
        "width": 50,
        "height": 50,
      }]
    }
    
    这解决了问题1和2,但没有解决问题3。并且在每个嵌入文档中添加一个额外的
    \u id
    字段。另外,当我插入一个新的化身时,我现在需要知道下一个要使用的
    \u id
    是什么(除非我使用objectId,但它是一个12字节的id,最多只能使用几百个化身)

    因此,另一个解决方案可能是:

    {
      "_id": ObjectId("515c99f7e4d8094a87e13757"),
      "active_avatar_id": 2,
      "avatars": [{
        "_id": 1,
        "url": "http://example.com/img/photo1.jpg",
        "width": 50,
        "height": 50,
      }, {
        "_id": 2,
        "url": "http://example.com/img/photo2.jpg",
        "width": 50,
        "height": 50,
      }]
    }
    
    {
      "_id": ObjectId("515c99f7e4d8094a87e13757"),
      "active_avatar": {
        "url": "http://example.com/img/photo2.jpg",
        "width": 50,
        "height": 50,
      },
      "extra_avatars": [{
        "url": "http://example.com/img/photo1.jpg",
        "width": 50,
        "height": 50,
      }]
    }
    
    不比第一个解决方案好多少(它只是解决了问题#3,就是这样,而且更难看)

    所有这些解决方案都是可行的,但我正在寻找“正确的方法”。有什么想法吗?如果我允许用户拥有多个活动的化身(无论这意味着什么),会怎么样


    谢谢。

    您是否考虑过文档模型中的文档

    {
        "_id" : ObjectId("515c99f7e4d8094a87e13758"),
        "active_avatar_id" : 2,
        "avatars" : {
            "1" : {
                "url" : "http://example.com/img/photo1.jpg",
                "width" : 50,
                "height" : 50
            },
            "2" : {
                "url" : "http://example.com/img/photo2.jpg",
                "width" : 50,
                "height" : 50
            }
        }
    }
    

    带有嵌入文档的文档实际上只是一个文档。它会一次更新所有文档。您可能希望有一个
    Users
    集合和一个
    Avatar
    集合(或者只在单个集合中更新文档)。一个用户文档将包含
    \u id
    头像
    。我建议您阅读该页面,了解MongoDB中的一些常见建模实践。@wiredPairie:我已经阅读了文档(顺便说一句,这很好),但我不确定我的示例的最佳实践是什么。根据您的第一条评论,我的问题1、2、3不存在,因此第一个选项似乎足够简单,它避免了在每个嵌入文档中需要_id。感谢您的建议。