MongoDB:在具有未知密钥的对象中查找给定字段值的文档

时间:2015-12-29 23:19:00

标签: mongodb mongodb-query

我正在制作关于这些/参数的数据库。它们与其他参数有关,我将它放在一个dynamic key的对象中,这是完全随机的。

{
    _id : "aeokejXMwGKvWzF5L",
    text : "test",
    relations : {
        cF6iKAkDJg5eQGsgb : {
            type : "interpretation",
            originId : "uFEjssN2RgcrgiTjh",
            ratings: [...]
         }
    }
}

如果我只知道type的价值是什么,我能找到这份文件吗?那就是我想做这样的事情:

db.theses.find({relations['anything']: { type: "interpretation"}}})

如果relations是一个数组,那么可以使用positional operator轻松完成。但是我无法对ratings中的对象进行更改,因为mongo doesn't support这些更新。我在这里问我是否可以不必更改数据库结构。

1 个答案:

答案 0 :(得分:2)

虽然由于使用嵌套数组的更新问题,您似乎已接近此结构,但您实际上只是通过执行其他不受支持的操作而导致另一个问题,那就是没有& #34;通配符" 概念,用于使用最佳的标准查询运算符搜索未指定的键。

您可以真正搜索此类数据的唯一方法是使用服务器上的JavaScript代码使用$where遍历密钥。这显然不是一个好主意,因为它需要强力评估,而不是像索引一样使用有用的东西,但可以按如下方式进行处理:

db.theses.find(function() {
    var relations = this.relations;
    return Object.keys(relations).some(function(rel) {
        return relations[rel].type == "interpretation";
    });
))

虽然这将从集合中返回包含所需嵌套值的那些对象,但它必须检查集合中的每个对象才能进行评估。这就是为什么这样的评估应该只在与可以直接使用索引的东西配对时使用,而不是作为集合中对象的硬值。

更好的解决方案是考虑重新构建数据以利用搜索中的索引。如果需要更新"评级"信息,然后基本上"展平" 结构,以考虑每个"评级"而element作为唯一的数组数据:

{
    "_id": "aeokejXMwGKvWzF5L",
    "text": "test",
    "relationsRatings": [
        {
            "relationId": "cF6iKAkDJg5eQGsgb",
            "type": "interpretation",
            "originId": "uFEjssN2RgcrgiTjh",
            "ratingId": 1,
            "ratingScore": 5
        },
        {
            "relationId": "cF6iKAkDJg5eQGsgb",
            "type": "interpretation",
            "originId": "uFEjssN2RgcrgiTjh",
            "ratingId": 2,
            "ratingScore": 6
        }
   ]
}

现在搜索当然很简单:

db.theses.find({ "relationsRatings.type": "interpretation" })

当然,positional $运算符现在可以用更扁平的结构:

db.theses.update(
    { "relationsRatings.ratingId": 1 },
    { "$set": { "relationsRatings.$.ratingScore": 7 } }
)

当然这意味着重复"相关"每个"评级的数据"值,但这通常是按匹配位置更新的成本,因为只有单级数组嵌套支持这一点。

因此,您可以强制逻辑与您的结构相匹配,但这样做并不是一个好主意,并且会导致性能问题。但是,如果您的主要需求是更新"评级"信息而不仅仅是附加到内部列表,然后更平坦的结构将带来更大的好处,当然搜索速度要快得多。