如何构建关联数组类型 O(1) 字段 n mongodb 模式

How to build a associative-array type O(1) field n mongodb schema

我最近才开始使用 Mongo,并且正在适应思考 文档 而不是 table 基于方法。

我的架构看起来像 (Node.js):

var UserInfo = new mongoose.Schema({
    id: Number,
    name: String,
    friends: [{
        id: Number,
        name: String,
    }]
    }, {
        collection: 'userInfo'
    });

问题是,如果我也知道我的用户 ID 和他朋友的 ID,我将不得不遍历整个 friends[] 来找到朋友。也就是说,整个操作不是O(1).

如果我将其存储在 JS 数据结构中,我将为朋友使用关联数组,像 myuser.friends[his_friend_id] 之类的东西会给我 O(1) 访问朋友的权限。如何在 Mongo 中实现相同的 O(1)?

我不熟悉 mongoose,但是如果按照您认为的那样创建结构有问题,那么这是有充分理由的。我目前的想法是,nosql 模式中的键永远不应该是动态的,因为它使搜索变得困难,如果不是不可能的话。

例如,使用您当前的架构,您将能够使用

之类的内容在好友属性中搜索用户
userInfo.find({ 'friends.id' = userId })

你也可以

userInfo.find({ id: userId, 'friends.id' = friendId })

但我不确定您是否可以 return 仅从搜索中获取个别朋友的数据。

如果您永远不需要做类似的事情,那么您似乎必须将关系存储在两个用户的文档中,从而复制数据。在这种情况下,您可能需要考虑一个简单地将朋友映射到朋友的集合,或者只将用户发起的关系存储在该用户的朋友列表中。

要回答实际问题,我认为您不想更改架构,而是继续加载用户并在好友列表中执行 filter/first/someother 类型数组搜索以找到匹配。

检索用户文档和获取朋友的整个操作永远不会是 O(1),因为 MongoDB 中的查找不是 O(1)。但是您可以避免在 friends 数组中搜索朋友。使用 $ 投影:

> db.test.drop()
> db.test.insert({ "_id" : 0, "friends" : [{ "_id" : 1 }, { "_id" : 2 }, { "_id" : 3 }] })
> db.test.find({ "_id" : 0, "friends._id" : 2 }, { "friends.$" : 1 })
{ "_id" : 0, "friends" : [ { "_id" : 2 } ] }

我要找的是 sub-document

Finding a sub-document

Each document has an _id. DocumentArrays have a special id method for looking up a document by its _id.

var doc = parent.children.id(id);