我正在开发一个 MERN 堆栈应用程序,其中 MongoDB 中有一个
Playlist
文档,如下所示:
{
_id: new ObjectId('663296c9ca082f17ba715a4c'),
name: 'My Fav 02',
videos: [ new ObjectId('6631c108d41dfb12d6d076cd') ],
userId: new ObjectId('6631bd463f5fe83acfb4913c'),
__v: 0
}
我正在尝试将 ObjectId 为“6631bd613f5fe83acfb49141”的视频添加到
videos
文档中的 Playlist
数组中。然而,我遇到了MongoServerError: E11000 duplicate key error
。该错误消息表明 videos
数组中已存在具有相同 ObjectId 的视频。但根据我的文档,仅存在“6631c108d41dfb12d6d076cd”的 ObjectId。
这是错误消息:
MongoServerError: E11000 duplicate key error collection: 64f7351729e1ad75103e28fa_test.playlists index: videos_1 dup key: { videos: ObjectId('6631bd613f5fe83acfb49141') }
这是我将视频添加到播放列表的 API:
router.put('/playlist/:id', authMiddleware, async (req, res) => {
try {
const playlist = await Playlist.findById(req.params.id);
if (playlist.userId.toString() !== req.body.userId) {
return res.status(403).json({ message: 'Forbidden' });
}
playlist.videos.push(req.body.videoId);
await playlist.save();
res.json({ message: 'Video added to playlist' });
} catch (err) {
res.status(500).json({ message: err.message });
}
});
我不确定为什么当我尝试添加的 ObjectId 不存在于
videos
数组中时会出现重复键错误。任何帮助将不胜感激。
您似乎在
videos
字段上有一个具有唯一约束的索引。我假设您这样做是为了保持数组中的值唯一。
但是数组字段上的索引不能以这种方式工作。它们包含该集合中任意文档的
videos
字段中存在的每个值的键(请参阅文档)
因此,当您的集合中现在有两个如下所示的文档时(此处简化了 ID,但您明白我的意思)
{
"userid": "user1",
"videos": ["video1", "video2"]
},
{
"userid": "user2",
"videos": ["video3", "video4"]
}
然后尝试将
video1
添加到 videos
的 user1
数组中,videos
字段上的索引将引发 duplicate key
错误,因为 video1
已存在于播放列表中 ...
我认为,目前没有任何方法可以创建一个索引来确保数组在文档中的唯一性。因此,您必须在应用程序级别进行此检查
const playlist = await Playlist.findById(req.params.id);
if (playlist.userId.toString() !== req.body.userId) {
return res.status(403).json({ message: 'Forbidden' });
}
if (playlist.videos.find(x => x.toString() === req.body.videoId)) {
return res.status(409).json({ message: 'Already exists' });
}
playlist.videos.push(req.body.videoId);
await playlist.save();
res.json({ message: 'Video added to playlist' });