MongoCollection:如何获取嵌套键的值

时间:2017-08-08 17:29:32

标签: java mongodb mongo-collection

我有一些看起来像这样的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的值?

UPADTE

非常感谢@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();

1 个答案:

答案 0 :(得分: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();