2017-08-08 41 views
0

值我有一個看起來像這樣MongoCollection:如何獲得的套疊的鍵

{ 
    "_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

你的數據樣本包含一個小寫的 「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(); 
+0

非常感謝你的幫助人!請在'include(「test」,「objects.key2.key4」)中看到我的更新 – AbtPst

+0

''爲什麼你使用'test'? – AbtPst

+1

對不起,這只是一個錯誤。我在查詢中使用了測試,然後在粘貼查詢作爲答案時將其更改。忘了在一個案例中做到這一點,現在將解決它。 – dnickless