【问题标题】:Getting existing Embedded Documents from Mongoose从 Mongoose 获取现有的嵌入式文档
【发布时间】:2012-12-20 08:27:55
【问题描述】:

我正在尝试在用户的文档中缓存来自社交媒体的朋友,但在存储/取回他们时遇到问题。 首先,我盲目地剥离了他们的朋友缓存,并用我新获取的数据填充它,但通过它我发现嵌入的文档在所有用户中必须是唯一的(我有几个相同的朋友在我的测试帐户中,我得到:

{"name":"MongoError","err":"E11000 duplicate key error index: test-dev.users.$friends.outsideID_1  dup key: { : \"1205314313242\" }","code":11001,"n":0,"connectionId":274,"ok":1} 

因此我知道,由于该嵌入文档存在于我的其他已注册和更新的帐户中,因此无法创建该文档(outsideID 是索引,因为我计划稍后使用它进行搜索)) 所以然后我开始尝试OutsideFriend.find({'outsideID':{$in:friendsIDs}}(其中friendsIDs是我从SM查询中获得的ID数组)等等。然后在我经历的回调中并尝试添加新朋友并将现有文档添加到有问题的用户,这样它就不会尝试在系统中复制它。但是,无论出于何种原因,OutsideFrind.find() 永远不会返回任何文档......这让我觉得嵌入式文档不是集中式的……但是为什么第一次尝试会失败?

我该怎么做? (下面的架构,如果您需要任何其他信息,请告诉我!)

当前架构:

//External friend model                                                                                                                                                                                              
var OutsideFriend = new Schema({
         outsideID:{type:String, index:true, unique:true}
        ,username:String
        ,location:String
        ,avatarURL:String
});

//User model                                                                                                                                                                                                         
var User = new Schema({
        avatarURL:String
       ,mySMID:String
    //Social Media info                                                                                                                                                                                                   
        ,smID:{type:String, index:true, unique:true}
        ,tok:String
        ,tokSec:String
        ,friends:[OutsideFriend]
};

【问题讨论】:

    标签: javascript mongodb mongoose


    【解决方案1】:

    您的问题有很多内容,但如果您想独立于User 查询OutsideFriend,那么您不应该将它们嵌入User 模型中。相反,只需将ObjectId 对朋友的引用存储,然后在需要完整详细信息时将populate 存储在User 中。除非您发现需要这样做,否则不要过早地使用嵌入式副本进行优化,因为这会带来一致性挑战。

    所以您的 User 模型将更改为:

    var User = new Schema({
        avatarURL:String
        //Social Media info
        ,smID:{type:String, index:true, unique:true}
        ,tok:String
        ,tokSec:String
        ,friends:[{type: ObjectId, ref: 'OutsideFriend'}]
    };
    

    【讨论】:

    • 嗯,最初的想法是在用户文档中缓存 SM 朋友的列表,因此想法是对该用户列表具有唯一性,我假设它们是完全独立的,所以如果 userA和 userB 都是 Bob 的朋友,没有问题,但显然我错了,因为我从中得到了上述错误。那么你打算怎么做呢?我可以将它移到 ref 并填充备用计划(可能是为了时间),但我真的很想知道这样做的“推荐”方法!^^
    • @MatthewClark 当您在数组字段中嵌入另一个模式(如friends)时,该模式中定义的任何索引也会在嵌入(父)模式的集合中创建。在这种情况下,唯一索引意味着没有两个User 文档可以在它们的friends 数组中包含同名的OutsideFriend。因此,嵌入包含唯一索引的模式很少是您想要的。我建议为friends 创建一个单独的架构,没有唯一索引,如果您仍想使用嵌入式方法,则该唯一索引仅包含您需要缓存的字段。
    • 您不认为嵌入式方法是最高效的方法吗?我将在这个缓存中搜索,以向用户显示他们的哪些 SM 朋友在这个系统上。
    • @MatthewClark 不要过早优化。 ObjectId 的查找速度非常快,因此通常不需要它。通常最好保持简单,直到您发现它不能为您提供所需的性能。
    • 很公平!感谢您的回复,我将快速对其进行测试,然后很可能会给您信用^^
    猜你喜欢
    • 2017-01-15
    • 2017-01-29
    • 2011-12-21
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 2013-12-16
    • 2014-01-29
    相关资源
    最近更新 更多