I have a collection that contains metrics about conferences and users on my website and I would like to store them by conference. Each conference has one or many users, and each user has one or many sessions, and each session has one or many metrics.
Here's an example of a conference document that I want to save :
{
"conf":"conference12345",
"users":[
{ //User 1
"uid":"2dd8b4e3-9dcd-4da6-bc36-aa0988dc9642",
"sessions":[
[// User 1 => session 1
{
"ts": 1234567891,
"br":"Chrome 92",
"os":"Windows",
},
{
"ts": 1234567899,
"bw":100
}
],
[// User 1 => session 2
{
"ts": 1234567900,
"br":"Chrome 92",
"os":"Windows",
},
{
"ts": 1234567950,
"bw":500
}
],
]
},
{ //User 2
"uid":"2dd8b4e3-9dcd-4da6-bc36-aa0988dc9666",
"sessions":[
[// User 2 => session 1
{
"ts": 1234567891,
"br":"Chrome 90",
"os":"Mac",
},
{
"ts": 1234567899,
"bw":100
}
]
]
}
]
}
I want to insert new data at once by using db.collection.update
with upsert
option. But I had a hard time figuring out how. Metrics should be added to the last element of "sessions" array.
Here's an example of data that I want to add :
// New user. a new document should be created because it's a new conference.
{
"conf": "conferenceXYZ",
"uid": "1cd8b4e3-9dcd-4da6-bc36-aa0988dc9512",
"metrics": {
"ts": 1234567891,
"br":"Chrome 90",
"os":"Mac",
}
}
// Existing user. metrics should be added to his last session
{
"conf": "conference12345",
"uid": "2dd8b4e3-9dcd-4da6-bc36-aa0988dc9642",
"metrics": {
"ts": 1234567891,
"bw":356
}
}
I tried to use update with upsert option but it's a difficult to find the missing pieces. Any help would be greatly appreciated.
Query
$set
is to put your dataupdate(
{"conf": "conference12345"},
[{"$set":
{"uid": "2dd8b4e3-9dcd-4da6-bc36-aa0988dc9642",
"usession": [{"ts": 1234567891, "bw": 356}]}},
{"$set":
{"new-user":
{"$eq":
[{"$filter":
{"input": {"$cond": ["$users", "$users", []]},
"as": "u",
"cond": {"$eq": ["$$u.uid", "$uid"]}}},
[]]}}},
{"$set":
{"users":
{"$cond":
["$new-user",
{"$concatArrays":
[{"$cond": [{"$isArray": ["$users"]}, "$users", []]},
[{"uid": "$uid", "sessions": ["$usession"]}]]},
{"$map":
{"input": "$users",
"as": "u",
"in":
{"$cond":
[{"$eq": ["$$u.uid", "$uid"]},
{"$mergeObjects":
["$$u",
{"sessions":
{"$concatArrays": ["$$u.sessions", ["$usession"]]}}]},
"$$u"]}}}]}}},
{"$unset": ["uid", "usession", "new-user"]}],
{"upsert": true, "multi": true})