MongoDB:在具有未知键的对象中查找给定字段值的文档 [英] MongoDB: Find document given field values in an object with an unknown key

查看:61
本文介绍了MongoDB:在具有未知键的对象中查找给定字段值的文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个关于论文/论点的数据库.它们与其他参数有关,我将它们放置在一个带有 动态键的对象中,这是完全随机的.

I'm making a database on theses/arguments. They are related to other arguments, which I've placed in an object with a dynamic key, which is completely random.

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

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

Can I find this document if I only know what the value of type is? That is I want to do something like this:

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

这可以通过 positional 轻松完成运算符,如果relations 是一个数组.但是后来我无法更改 ratings 中的对象,因为 mongo 不会支持这些更新.我在这里问我是否可以不必更改数据库结构.

This could've been done easily with the positional operator, if relations had been an array. But then I cannot make changes to the objects in ratings, as mongo doesn't support those updates. I'm asking here to see if I can keep from having to change the database structure.

推荐答案

尽管您似乎由于使用嵌套数组的更新问题而接近此结构,但您实际上只是通过执行其他不受真正支持的操作而引起了另一个问题,那就是没有 "通配符" 概念,用于使用最佳的标准查询运算符搜索未指定的键.

Though you seem to have approached this structure due to a problem with updates in using nested arrays, you really have only caused another problem by doing something else which is not really supported, and that is that there is no "wildcard" concept for searching unspecified keys using the standard query operators that are optimal.

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

The only way you can really search for such data is by using JavaScript code on the server to traverse the keys using $where. This is clearly not a really good idea as it requires brute force evaluation rather than using useful things like an index, but it can be approached as follows:

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

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

While this will return those objects from the collection that contain the required nested value, it must inspect each object in the collection in order to do the evaluation. This is why such evaluation should really only be used when paired with something that can directly use an index instead as a hard value from the object in the collection.

仍然更好的解决方案是考虑重构数据以利用搜索中的索引.如果需要更新评级"信息,则基本上扁平化" 将每个评级"元素视为唯一数组数据的结构:

Still the better solution is to consider remodelling the data to take advantage of indexes in search. Where it is neccessary to update the "ratings" information, then basically "flatten" the structure to consider each "rating" element as the only array data instead:

{
    "_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 $ 运算符现在可以与更扁平的结构一起使用:

And of course the positional $ operator can now be used with the flatter structure:

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

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

Of course this means duplication of the "related" data for each "ratings" value, but this is generally the cost of being to update by matched position as this is all that is supported with a single level of array nesting only.

因此您可以强制逻辑与您的结构方式相匹配,但这不是一个好主意,并且会导致性能问题.然而,如果您在这里的主要需求是更新评级"信息而不是仅仅附加到内部列表,那么更扁平的结构将更有好处,当然搜索速度也会更快.

So you can force the logic to match with the way you have it structured, but it is not a great idea to do so and will lead to performance problems. If however your main need here is to update the "ratings" information rather than just append to the inner list, then a flatter structure will be of greater benefit and of course be a lot faster to search.

这篇关于MongoDB:在具有未知键的对象中查找给定字段值的文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆