MongoDB: 使用引用作为键并手动添加值
MongoDB: Using reference as key and manually adding a value
我是 Mongo 数据库的新手,遇到以下问题。
假设我有这样的文档结构,其中用户 Joe Bloggs 观看了一个内容,该内容用 ID 5000 引用:
db.users.insert({
forname: 'Joe',
surname: 'Bloggs',
DOB: 12061989,
watch: [5000]
});
db.media_content.insert({
_id: 5000,
content_name: 'Film XYZ',
durations_min: 45,
media_type: 'video',
});
我想补充一点,用户 Joe Bloggs 只观看了 35 分钟的 Film XYZ,然而它的时长是 45 分钟。如果我想证明 Joe Bloggs 观看了 Film XYZ 的时间为 35 分钟,我将如何添加它以及查询会是什么样子。
--- 更新 ---
我没有进行更新,而是重新编码以便尝试:
db.users.insert({
forname: 'Tom',
surname: 'Smith',
DOB: 22081989,
watch: [{
media_id: 6000,
stream_min: 35
}]
});
db.media_content.insert({
_id: 6000,
content_name: 'Film XYZ',
durations_min: 45,
media_type: 'video',
});
var minutes_watched = db.users.find(
{
"forname": "Tom",
"surname": "Smith",
"DOB": 22081989,
"watch.media_id": 6000
},
{
"watch": {
"$elemMatch": { "media_id": 6000 }
}
}).watch[0].minutes_watched;
我以为我成功了,但我仍然收到消息:
TypeError: Cannot read property 'watch' of null.
我做错了什么?
您可以重组您的文档架构,使 watch
数组将转换为同时具有参考 ID 和观看分钟数属性的嵌入式文档,而不是仅具有 ID 值的数组.像这样 $push
更新应该做的事情:
db.users.update({
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989,
"watch": 5000
},
{
"$push": {
"watch": {
"media_id": 5000,
"minutes_watched": 35
}
}
}
);
以上更新了用户 "Joe" 的用户文档,以在具有上述属性的 watch
数组中添加嵌入文档。为了整理一下,您可以 $pull
另一个 watch
值为 5000
的数组元素
db.users.update({
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989,
"watch": 5000
},
{
"$pull": { "watch": 5000 }
}
);
既然你现在有实际的观看时长和媒体 ID 详细信息都嵌入在用户文档中,你可以查询给定媒体 ID 的两个集合以获取观看分钟数(使用 $elemMatch
watch
数组以投影该字段)和电影详细信息如下:
var minutes_watched = db.users.findOne(
{
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989,
"watch.media_id": 5000
},
{
"watch": {
"$elemMatch": { "media_id": 5000 }
}
}).watch[0].minutes_watched;
var movie = db.media_content.findOne({"_id": 5000});
编辑
如果用户再观看 2 部电影,一部 ID 为 4567 的电影在总共 80 分钟中观看了 20 分钟,另一部 ID 为 1234 的电影观看了 58 分钟,您只需将这些详细信息推送到 watch
数组使用 $addToSet
with $each
像这样:
db.users.update({
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989
},
{
"$addToSet": {
"watch": {
$each: [
{ "media_id": 4567, "minutes_watched": 20 },
{ "media_id": 1234, "minutes_watched": 58 }
]
}
}
}
);
对用户 "Joe" db.users.findOne({"forname": "Joe"})
的查询将产生更新后的文档:
/* 1 */
{
"_id" : ObjectId("553d143ac96712b936005274"),
"forname" : "Joe",
"surname" : "Bloggs",
"DOB" : 12061989,
"watch" : [
{
"media_id" : 5000,
"minutes_watched" : 35
},
{
"media_id" : 4567,
"minutes_watched" : 20
},
{
"media_id" : 1234,
"minutes_watched" : 58
}
]
}
我是 Mongo 数据库的新手,遇到以下问题。 假设我有这样的文档结构,其中用户 Joe Bloggs 观看了一个内容,该内容用 ID 5000 引用:
db.users.insert({
forname: 'Joe',
surname: 'Bloggs',
DOB: 12061989,
watch: [5000]
});
db.media_content.insert({
_id: 5000,
content_name: 'Film XYZ',
durations_min: 45,
media_type: 'video',
});
我想补充一点,用户 Joe Bloggs 只观看了 35 分钟的 Film XYZ,然而它的时长是 45 分钟。如果我想证明 Joe Bloggs 观看了 Film XYZ 的时间为 35 分钟,我将如何添加它以及查询会是什么样子。
--- 更新 ---
我没有进行更新,而是重新编码以便尝试:
db.users.insert({
forname: 'Tom',
surname: 'Smith',
DOB: 22081989,
watch: [{
media_id: 6000,
stream_min: 35
}]
});
db.media_content.insert({
_id: 6000,
content_name: 'Film XYZ',
durations_min: 45,
media_type: 'video',
});
var minutes_watched = db.users.find(
{
"forname": "Tom",
"surname": "Smith",
"DOB": 22081989,
"watch.media_id": 6000
},
{
"watch": {
"$elemMatch": { "media_id": 6000 }
}
}).watch[0].minutes_watched;
我以为我成功了,但我仍然收到消息:
TypeError: Cannot read property 'watch' of null.
我做错了什么?
您可以重组您的文档架构,使 watch
数组将转换为同时具有参考 ID 和观看分钟数属性的嵌入式文档,而不是仅具有 ID 值的数组.像这样 $push
更新应该做的事情:
db.users.update({
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989,
"watch": 5000
},
{
"$push": {
"watch": {
"media_id": 5000,
"minutes_watched": 35
}
}
}
);
以上更新了用户 "Joe" 的用户文档,以在具有上述属性的 watch
数组中添加嵌入文档。为了整理一下,您可以 $pull
另一个 watch
值为 5000
db.users.update({
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989,
"watch": 5000
},
{
"$pull": { "watch": 5000 }
}
);
既然你现在有实际的观看时长和媒体 ID 详细信息都嵌入在用户文档中,你可以查询给定媒体 ID 的两个集合以获取观看分钟数(使用 $elemMatch
watch
数组以投影该字段)和电影详细信息如下:
var minutes_watched = db.users.findOne(
{
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989,
"watch.media_id": 5000
},
{
"watch": {
"$elemMatch": { "media_id": 5000 }
}
}).watch[0].minutes_watched;
var movie = db.media_content.findOne({"_id": 5000});
编辑
如果用户再观看 2 部电影,一部 ID 为 4567 的电影在总共 80 分钟中观看了 20 分钟,另一部 ID 为 1234 的电影观看了 58 分钟,您只需将这些详细信息推送到 watch
数组使用 $addToSet
with $each
像这样:
db.users.update({
"forname": "Joe",
"surname": "Bloggs",
"DOB": 12061989
},
{
"$addToSet": {
"watch": {
$each: [
{ "media_id": 4567, "minutes_watched": 20 },
{ "media_id": 1234, "minutes_watched": 58 }
]
}
}
}
);
对用户 "Joe" db.users.findOne({"forname": "Joe"})
的查询将产生更新后的文档:
/* 1 */
{
"_id" : ObjectId("553d143ac96712b936005274"),
"forname" : "Joe",
"surname" : "Bloggs",
"DOB" : 12061989,
"watch" : [
{
"media_id" : 5000,
"minutes_watched" : 35
},
{
"media_id" : 4567,
"minutes_watched" : 20
},
{
"media_id" : 1234,
"minutes_watched" : 58
}
]
}