MongoServerError:尝试将视频添加到 MongoDB 中的播放列表时出现 E11000 重复键错误

问题描述 投票:0回答:1

我正在开发一个 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
数组中时会出现重复键错误。任何帮助将不胜感激。

javascript mongodb express mongoose mongodb-query
1个回答
0
投票

您似乎在

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' });
    
© www.soinside.com 2019 - 2024. All rights reserved.