【问题标题】:MongoCollection : How to get value of nested keyMongoCollection:如何获取嵌套键的值
【发布时间】:2017-08-08 17:29:32
【问题描述】:

我有一些看起来像这样的 mongo 数据

{
    "_id": {
        "$oid": "5984cfb276c912dd03c1b052"
    },
    "idkey": "123",
    "objects": [{
        "key1": "481334",
        "key2": {
            "key3":"val3",
            "key4": "val4"
        }
    }]

}

我想知道key4 的值是多少。我还需要通过idkeykey1 过滤结果。所以我尝试了

doc = mongoCollection.find(and(eq("idKey", 123),eq("objects.key1", 481334))).first();

这行得通。但我想检查key4 的值,而不必打开整个对象。是否有一些我可以执行的查询只给我key4 的值?请注意,我可以将key4 的值更新

mongoCollection.updateOne(and(eq("idKey", 123), eq("objects.key1", 481334)),Updates.set("objects.$.key2.key4", "someVal"));

我是否可以运行类似的查询来获取key4 的值?

更新

非常感谢@dnickless 的帮助。我尝试了你的两个建议,但我得到了空值。这是我尝试过的

existingDoc = mongoCollection.find(and(eq("idkey", 123), eq("objects.key1", 481334))).first();

这给了我

Document{{_id=598b13ca324fb0717c509e2d, idkey="2323", objects=[Document{{key1="481334", key2=Document{{key3=val3, key4=val4}}}}]}}

到目前为止一切顺利。接下来我尝试了

mongoCollection.updateOne(and(eq("idkey", "123"), eq("objects.key1", "481334")),Updates.set("objects.$.key2.key4", "newVal"));

现在我尝试将更新后的文档作为

updatedDoc = mongoCollection.find(and(eq("idkey", "123"),eq("objects.key1","481334"))).projection(Projections.fields(Projections.excludeId(), Projections.include("key4", "$objects.key2.key4"))).first();

为此我得到了

Document{{}}

最后我尝试了

updatedDoc = mongoCollection.aggregate(Arrays.asList(Aggregates.match(and(eq("idkey", "123"), eq("objects.key1", "481334"))),
                            Aggregates.unwind("$objects"), Aggregates.project(Projections.fields(Projections.excludeId(), Projections.computed("key4", "$objects.key2.key4")))))
                    .first();

为此我得到了

Document{{key4="newVal"}}

所以我很高兴 :) 但是你能想出第一种方法不起作用的原因吗?

最终答案

感谢@dnickless 的更新

document = collection.find(and(eq("idkey", "123"), eq("objects.key1", "481334"))).projection(fields(excludeId(), include("key4", "objects.key2.key4"))).first();

【问题讨论】:

    标签: java mongodb mongo-collection


    【解决方案1】:

    您的数据样本包含一个小写的“idkey”,而您的查询使用“idKey”。在下面的示例中,我使用小写版本。此外,您正在查询整数 123 和 481334,而不是在查看您的示例数据时正确的字符串。我将使用下面的代码获取字符串版本,以使其适用于提供的示例数据。

    你有两个选择:

    您可以简单地限制结果集,但使用简单的查找 + 投影保持相同的结构:

    document = collection.find(and(eq("idkey", "123"), eq("objects.key1", "481334"))).projection(fields(excludeId(), include("objects.key2.key4"))).first();
    

    或者,在输出方面可能更好(但不一定是速度),您使用聚合框架来真正得到您想要的:

    document = collection.aggregate(Arrays.asList(match(and(eq("idkey", "123"), eq("objects.key1", "481334"))), unwind("$objects"), project(fields(excludeId(), computed("key4", "$objects.key2.key4"))))).first();
    

    【讨论】:

    • in include("test", "objects.key2.key4") 你为什么用test
    • 对不起,这只是一个错误。我在查询中使用了测试,然后在将查询粘贴为答案时对其进行了更改。有一种情况忘记了,现在就修。
    • 谢谢!第二种方法有效,但正如你所说,它需要更多时间。知道为什么我使用第一种方法时可能会得到一个空白文档吗?
    • 等一下,第一个查询还有一些问题。我很困惑,因为我在这里打字时正在处理一些复杂的东西。我会为你解决这个问题。
    • 不,$ 符号仅适用于聚合框架版本。那一定是复制和粘贴问题。无论如何,我修复了另一件事:根本不需要“key4”的东西(以前是“测试”)......;)所以,现在,我想,我们得到了最终版本......唷!
    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 2016-10-31
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多