【问题标题】:MongoDB embedded vs array sub document performanceMongoDB 嵌入式 vs 数组子文档性能
【发布时间】:2012-11-18 06:07:10
【问题描述】:

鉴于以下具有多达 100,000 位朋友的竞争模式,我有兴趣找到最能满足我需求的模式。

Doc1(user_id 上的索引)

{
"_id" : "…",
"user_id" : "1",
friends : {
    "2" : {
        "id" : "2",
        "mutuals" : 3
    }
     "3" : {
         "id" : "3",
         "mutuals": "1"
    }
   "4" : {
         "id" : "4",
         "mutuals": "5"
    }
}
}

Doc2(user_id 和friends.id 上的复合多键索引)

{
"_id" : "…",
"user_id" : "1",
friends : [
   {
        "id" : "2",
        "mutuals" : 3
    },
    {
         "id" : "3",
         "mutuals": "1"
    },
   {
         "id" : "4",
         "mutuals": "5"
    }
]}

我似乎找不到任何关于子字段检索效率的信息。我知道 mongo 在内部将数据实现为 BSON,所以我想知道这是否意味着投影查找是二进制 O(log n)?

具体来说,给定一个 user_id 来查找是否存在具有friend_id 的朋友,每个模式上的两个不同查询将如何比较? (假设上面的索引)注意返回什么并不重要,如果朋友存在则返回 not null。

Doc1col.find({user_id : "…"}, {"friends.friend_id"})
Doc2col.find({user_id : "…", "friends.id" : "friend_id"}, {"_id":1})

同样有趣的是 $set 修饰符是如何工作的。对于模式 1,给定查询 Doc1col.update({user_id : "…"}, {"$set" : {"friends.friend_id.mutuals" : 5}),查找 friends.friend_id 是如何工作的?这是一个 O(log n) 操作(其中 n 是朋友的数量)吗?

对于模式 2,查询 Doc2col.update({user_id : "…", "friends.id" : "friend_id"}, {"$set": {"friends.$.mutuals" : 5}) 与上述查询相比如何?

【问题讨论】:

  • 使用数组样式 (Doc2),因为动态键几乎从来都不是正确的方法。另外,不要使用智能引号(这不是合法的语法,而且很难阅读)。
  • 我想 Doc2 会用掉几个字节的额外存储空间,但正如@JohnnyHK 所说,Doc1 并不是一个真正的好方法,相信我使用 Doc1 的人提出的问题数量然后意识到他们有转移到 Doc2 以对他们的架构做任何事情......
  • 感谢您的建议。 @Sammaye 为什么 Doc2 会占用几个字节的额外存储空间?你指的是指数吗?顺便说一句,智能引号是复制粘贴的错误
  • 两者之间的索引应该是相对相同的大小,嗯我可能错了实际上我认为对象数组比其他自定义对象的自定义对象要小,无论哪种方式我认为存储的差异几乎可以忽略不计。
  • 这个问题已经在这里被问到/回答得很好:stackoverflow.com/questions/8077514/…。对我来说,关键点似乎是动态键方法不可索引。

标签: arrays mongodb nosql


【解决方案1】:

如果一个人的主要要求是在一个易于管理的包中向用户界面呈现数据,则最好使用 doc1。使用投影{}, {friends.2 : 1}

仅过滤所需数据很简单

doc2 是您的最佳匹配,因为您的用例不关心结果请注意,返回的内容并不重要,索引会加快获取速度。

在 doc2 之上允许更简洁的语法

db.doc2.findOne({user_id: 1, friends.id : 2} )

db.doc1.findOne({ $and : [{ user_id: 1 }, { "friends.2" : {$exists: true} }] })

最后一点,然而,可以在 doc1 上创建一个 sparse index(并使用 $exists),但是您可能有 100,000 个朋友——每个朋友都需要一个稀疏索引——这很荒谬。相对于合理数量的条目来说,人口统计性别 [男性,女性],年龄组 [0-10,11-16,25-30,..] 或更多暗示的东西 [杜松子酒,威士忌,伏特加,...]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 2015-02-06
    • 2020-11-22
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多