聚合过滤器的Key

时间:2014-12-29 21:36:00

标签: mongodb mongodb-query

如果我有如下文件:

{
    "_id" : ObjectId("54986d5531a011bb5fb8e0ee"),
    "owner" : "54948a5d85f7a9527a002917",
    "type" : "group",
    "deleted" : false,
    "participants" : {
            "54948a5d85f7a9527a002917" : {
                    "last_message_id" : null
            },
            "5491234568f7a9527a002917" : {
                    "last_message_id" : null
            }
            "1234567aaaa7a9527a002917" : {
                    "last_message_id" : null
            }
    },
  }

如何对参与者“54948a5d85f7a9527a002917”的所有文件进行简单过滤?

由于

1 个答案:

答案 0 :(得分:1)

尝试查询这样的结构效果不佳。像这样的建模有很多问题,但最明显的问题是使用"数据"作为"键的名称"。

尝试考虑一点RDBMS,至少在数据库不能或不应该做的限制的概念中。你不会设计一个"表"在一个类似" 54948a5d85f7a9527a002917"作为"列"这个名字现在好吗?但这基本上就是你在这里所做的。

MongoDB可以查询,但不能以有效的方式查询:

db.collection.find({ 
    "participants.54948a5d85f7a9527a002917": { "$exists": true }
})

当然,这会寻找"存在"数据中的一个键。虽然查询表单是可用的,但它并没有有效地使用索引等可用的索引,因为索引适用于"数据"而不是"键"名。

更好的结构和方法是:

{
    "_id" : ObjectId("54986d5531a011bb5fb8e0ee"),
    "owner" : "54948a5d85f7a9527a002917",
    "type" : "group",
    "deleted" : false,
    "participants" : [
        { "_id": "54948a5d85f7a9527a002917" },
        { "_id": "5491234568f7a9527a002918" },
        { "_id": "1234567aaaa7a9527a002917" }
    ]
}

现在"数据"你正在寻找的是实际的数据"与"键"相关联(可能)和一个用于绑定父对象的数组。查询效率更高:

db.collection.find({
    "participants._id": "54948a5d85f7a9527a002917"
})

以这种方式建模比你现在做的要好得多,而且消耗对象也是有意义的。

顺便说一句。它可能只是剪切和粘贴你的问题,但你不能复制键,如" 54948a5d85f7a9527a002917"就像你一样。这是一个在那里被打破的基本哈希规则。