我一直在尝试在我的node.js后端的mongoDb数据库中组合应用唯一索引,但无法摆脱重复错误

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

电影应该添加到名为所有用户的观看列表的单个文档中,但我尝试结合 profile_id(user) 和 content_id(movie_id) 应用唯一索引,以便可以将同一部电影添加到不同的数据库中可以为同一用户添加不同的用户和不同的电影。但是当我尝试使用不同的电子邮件登录后添加同一部电影时,仍然显示重复的错误(error.code === 11000)。

const mongoose = require('mongoose')
const {ObjectId} = mongoose.Schema.Types

const WatchlistSchema = new mongoose.Schema({
    profile_id: { type: mongoose.Schema.Types.ObjectId, required: true, ref:'user'},
    content_id:{type:Number, required:true},
    mediaType:{type:String,required:true},
    title:{type:String, required:true}
})

WatchlistSchema.index({ profile_id: 1, content_id: 1 },{unique: true});

const WatchListModel = mongoose.model('watchlist',WatchlistSchema)

module.exports = WatchListModel

这是架构和模型

WatchlistRouter.post('/list',async(req, res)=>{
    const {list_id,media_type,name,ActiveUser} = req.body
    try {
        const user = await UserModel.findOne({email:ActiveUser})
        if(user){
            try {
                const entry = new WatchListModel({profile_id:user._id,content_id:list_id,mediaType:media_type,title:name})
                await WatchListModel.create(entry)
                res.status(200).send('Added to Watchlist successfully')
                
            } catch (error) {
                if (error.code === 11000) {
                    res.status(400).send(`This item is already in the watchlist for this ${ActiveUser }.`);
                } else {
                    res.status(500).send(`An error occurred: ${error.message}`);
                }
            }
        }else{
            res.status(400).send('You are not logged in to access this feature')
        }
        
    } catch (error) {
        res.status(500).send({message:error.message})
    }
})

这是添加电影的后期操作

我确实可以选择通过使用相关逻辑在控制器中处理这个问题,但我认为如果处理适当的模型设计,它会更合适。我尝试通过控制台不同部分进行调试,并搜索了整个网络,但无法理解原因。

node.js mongodb-query duplicates mern mongoose-schema
1个回答
0
投票

我看到您正在尝试创建一个集合,其中每个文档都包含用户 ID 和电影 ID。 user_id 和 movie_id 组合上的唯一索引应该可以防止同一用户多次添加同一部电影,但问题可能是索引创建不正确,这可能导致它分别检查 user_id 和 movie_id 而不是检查它作为一个组合。尝试通过

getIndexes()
命令获取所有索引并检查它是否正确。如果正确但仍然不起作用,请尝试删除索引并重新创建它。

但是我建议您将电影存储在一个集合中,将用户存储在另一个集合中,然后向用户集合添加一个电影 ID 数组,这样您就可以存储用户添加到其观看列表中的所有电影,这会缩短加载时间更快、更高效,因为如果您获得 10 部电影,每个用户都会添加到观看列表中,并且您有 100 个用户,那么您将拥有 1000 个文档,并且 MongoDB 必须搜索所有文档才能找到用户文档,如果您有的话这样你只需要去用户id并通过id检索每个电影信息,读取起来会更快。

const MovieSchema = new mongoose.Schema({
    movie_id: { type: Number, required: true },
    mediaType: { type: String, required: true },
    title: { type: String, required: true }
});

const WatchlistSchema = new mongoose.Schema({
    profile_id: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'user' },
    profileName: { type: String, required: true },
    movies: [{ type: Number }]
});

也用

updateOne( { profile_id: userId }, 
           { $addToSet: { movies: movieId } } )

向用户添加电影时,如果 moddedCount 返回

0
则表示未添加该电影,如果返回
1
则表示已添加该电影,因为
$addToSet
运算符仅将元素添加到数组中(如果未添加)如果matchedCount返回
0
,则表示它还没有找到任何具有该id的用户,如果它返回
1
,则表示它找到了具有该id的用户。

© www.soinside.com 2019 - 2024. All rights reserved.