查询具有给定值的内部子字段的文档

时间:2015-07-25 23:24:11

标签: mongodb mongodb-query

我在MongoDB的集合x上有这样的文档:

{
    "_id" : ...
    "attrKeys": [ "A1", "A2" ],
    "attrs" : {
        "A1" : {
            "type" : "T1",
            "value" : "13"
        },
        "A2" : {
            "type" : "T2",
            "value" : "14"
        }
    }
}

上面的A1A2元素只是示例:attrs字段可以包含任意数量的任意名称的键。 attrs中的密钥名称存储在attrNames字段中。

我想查询具有attr且具有给定值的子字段的文档。例如,对attr键映射中具有子字段type的元素的文档的查询是" T4"。像这样:

db.x.find({"attrs.$any.type": "T4"})

(avobe不是合法的MongoDB查询语言,但我认为它有助于理解这一点。)

MongoDB可以进行查询吗?在MongoDB不支持该查询的情况下是否有任何解决方法?谢谢!

编辑:数据模型的原始版本使用attrs的数组而不是键映射。但是,为了允许在同一文档上进行并发修改,这改变了有利于键映射。

我的意思是,使用键映射两个独立的客户端可以修改attrs元素,因为一个客户端可以db.x.update({_id: "y"}, {$set: { "attrs.A1.value": "12" } }而另一个客户端db.x.update({_id: "y"}, {$set: { "attrs.A2.value": "55" } }可以互相干扰。

在使用数组的情况下,并发访问要困难得多。有关如何做到的任何提示吗?

1 个答案:

答案 0 :(得分:1)

MongoDB始终可以实现这一点,因为始终能够使用JavaScript evaluation构建查询条件:

db.attrs.find(function() {
    var attrs = this.attrs;
    return Object.keys(attrs).some(function(key) {
       return attrs[key].value === "14"
    });
})

通过在文档中搜索所需值的可能键,它将正确返回与此条件匹配的文档。

但这不是一个关于“可能”的问题,但是“更多的是这个真的好主意”,其基本答案是“不”。

数据库是变幻无常的野兽,喜欢用索引之类的东西进行优化,以及他们自己期望的运算符集,以使搜索尽可能高效地使用。所以,是的,您可以通过一个语言解释器,有效的暴力评估每个文档的编码条件,或者您可以重新考虑您的设计模式。

数据库喜欢“订单”,所以给它一些,因为你建议的数据有一个简单有组织的重组:

{
    "attrs" : [
        { "key": "A1", "type" : "T1", "value" : "13" },
        { "key": "A2", "type" : "T2", "value" : "14" }
     ]
}

以这种方式组织查询变得如此简单:

db.attrs.find({ "attrs.value": "14" })

当然可以在数组子文档的任何属性上支持和使用索引。

MongoDB毕竟是一个“数据库”,并且像所有数据库一样,它最关心的是它的属性的“值”,而不是使用它的“密钥”的名称进行搜索。所以代表有意义的“数据”的东西不应该是“关键”名称的一部分,而应该是“关键”作为“标识符”的“价值”,如上所示。

使用您希望查询的数据的一致路径是在MongoDB中处理数据的最佳方式。使用密钥名称正在发生变化的结构,除了运行代码之外的其他任何东西都不能遍历,并且这么慢,而且性能比使用索引等本机操作和设施更差。