所以,我需要的不是恰好是的一個連接,而是非常相似的東西。主要區別是我需要的所有數據都在同一個集合中。我見過的其他與MongoDB中的連接有關的答案都在集合之間。從一個查詢中獲取不同類型文檔的數據
在我的收藏中,我有不同類型的文檔。
例如起見,考慮這兩個:
{
"success" : true,
"action" : "logEventGA",
"timestamp" : 1490795738759,
"terminal" : "3533322585",
"device" : {
"cordova" : "4.3.0",
"model" : "iPhone8,1",
"platform" : "iOS",
"uuid" : "785ED0AB-996D-4E54-8E0F-404FE076BE4F",
"version" : "10.2.1",
"manufacturer" : "Apple",
"isVirtual" : false,
"serial" : "unknown"
},
"action_GA" : "login"
}
和
{
"success" : true,
"action" : "loginAttempt",
"timestamp" : 1483125811453,
"terminal" : "3533322585",
"id": {
"doc": 23324355,
"valid": true
}
"httpCode" : NumberInt("200")
}
每一個的定義特徵是它們action
。根據action
,對象將具有不同的信息。因此,我需要一個查詢來獲取來自這兩種文檔(動作「loginAttempt」和「logEventGA」)的信息,並且匹配(join?)它們 - 在這種情況下,我們可以使用terminal
屬性。
我試着在第一種文檔上運行查詢,而不是forEach
來獲取其他類型文檔的剩餘數據(順序無關緊要),但是速度很慢。此外,每個操作還有其他標準(例如,當action = loginAttempt時,httpCode必須是200)。有沒有辦法一次完成這一切?
以下是我對「表現不佳」的「加入」的嘗試。每行處理需要兩秒鐘的時間,而且它似乎越來越慢。不能使用這個。
db.Logging.find({
"timestamp": { $gte: new Date('2017-04-01').getTime() },
"action":"loginAttempt",
"httpCode": 200
}, {
terminal: 1,
"id.doc": 1,
_id: 0
}).forEach(function(obj) {
let eventGA = db.Logging.findOne({"terminal":obj.terminal, "action_GA":"login"},{ _id:0, "device.uuid":1});
console.log(obj.terminal+';'+obj.id.doc+';'+eventGA.device.uuid);
});
預期的結果將是這樣的(以CSV形式或作爲在我上面的代碼):
{
"terminal": 3533322585, // from either doc
"uuid": "785ED0AB-996D-4E54-8E0F-404FE076BE4F", // from "logEventGA"
"doc": 23324355 // from "loginAttempt"
}
您的預期結果是什麼?你總是有行動成對嗎?類似於'db.collection.aggregate({$ match:{action:{$ in:[「logEventGA」,「loginAttempt」]}},{$ group:{_ id:「$ terminal」,first:{「$第一個「:」$$ ROOT「},第二個:{」$ last「:」$$ ROOT「}}})'。上面的查詢通過'terminal'匹配'actions'和group並且投影這兩個文檔。 – Veeram
我編輯了問題並添加了預期結果。 另外,當action = loginAttempt時,我需要第二個條件,還有一個用於logEventGA。我會怎麼做呢? –
您可以在3.2版本及以下版本中使用'$ cond'表達式,在'$ project'階段使用3.4版本的'$ switch'。 – Veeram