mongodb update/upsert 和嵌套数组
mongodb update/upsert and nested arrays
我有一个 collection,其中包含有关我网站上的会议和用户的指标,我想按会议存储它们。每个会议有一个或多个用户,每个用户有一个或多个session,每个session有一个或多个指标。
以下是我要保存的会议文档示例:
{
"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
}
]
]
}
]
}
我想通过使用带有 upsert
选项的 db.collection.update
立即插入新数据。但我很难弄清楚怎么做。指标应添加到“sessions”数组的最后一个元素。
这是我要添加的数据示例:
// 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
}
}
我尝试使用带有更新插入选项的更新,但很难找到丢失的部分。任何帮助将不胜感激。
查询
- 第一个过滤器/
$set
是把你的数据
- 检查是否有新用户(它的新用户以防更新或找不到用户)
- 如果新用户推送新用户
否则找到用户并添加新会话
update(
{"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})
我有一个 collection,其中包含有关我网站上的会议和用户的指标,我想按会议存储它们。每个会议有一个或多个用户,每个用户有一个或多个session,每个session有一个或多个指标。
以下是我要保存的会议文档示例:
{
"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
}
]
]
}
]
}
我想通过使用带有 upsert
选项的 db.collection.update
立即插入新数据。但我很难弄清楚怎么做。指标应添加到“sessions”数组的最后一个元素。
这是我要添加的数据示例:
// 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
}
}
我尝试使用带有更新插入选项的更新,但很难找到丢失的部分。任何帮助将不胜感激。
查询
- 第一个过滤器/
$set
是把你的数据 - 检查是否有新用户(它的新用户以防更新或找不到用户)
- 如果新用户推送新用户 否则找到用户并添加新会话
update(
{"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})