MongoCollection:如何获取嵌套键的值
MongoCollection : How to get value of nested key
我有一些 mongo 数据看起来像这样
{
"_id": {
"$oid": "5984cfb276c912dd03c1b052"
},
"idkey": "123",
"objects": [{
"key1": "481334",
"key2": {
"key3":"val3",
"key4": "val4"
}
}]
}
我想知道key4
的值是多少。我还需要按 idkey
和 key1
过滤结果。所以我尝试了
doc = mongoCollection.find(and(eq("idKey", 123),eq("objects.key1", 481334))).first();
这行得通。但是我想检查 key4
的值而不必打开整个对象。是否有一些我可以执行的查询只给我 key4
的值?请注意,我可以 update key4
的值作为
mongoCollection.updateOne(and(eq("idKey", 123), eq("objects.key1", 481334)),Updates.set("objects.$.key2.key4", "someVal"));
有没有类似的查询我可以运行只是为了得到key4
的值?
更新
非常感谢@dnickless 的帮助。我尝试了你的两个建议,但我得到了 null。这是我试过的
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();
您的数据样本包含小写 "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();
我有一些 mongo 数据看起来像这样
{
"_id": {
"$oid": "5984cfb276c912dd03c1b052"
},
"idkey": "123",
"objects": [{
"key1": "481334",
"key2": {
"key3":"val3",
"key4": "val4"
}
}]
}
我想知道key4
的值是多少。我还需要按 idkey
和 key1
过滤结果。所以我尝试了
doc = mongoCollection.find(and(eq("idKey", 123),eq("objects.key1", 481334))).first();
这行得通。但是我想检查 key4
的值而不必打开整个对象。是否有一些我可以执行的查询只给我 key4
的值?请注意,我可以 update key4
的值作为
mongoCollection.updateOne(and(eq("idKey", 123), eq("objects.key1", 481334)),Updates.set("objects.$.key2.key4", "someVal"));
有没有类似的查询我可以运行只是为了得到key4
的值?
更新
非常感谢@dnickless 的帮助。我尝试了你的两个建议,但我得到了 null。这是我试过的
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();
您的数据样本包含小写 "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();