猫鼬模式的最有效结构

时间:2018-09-16 07:37:33

标签: node.js database mongodb mongoose database-design

我很好奇构造猫鼬模式的最佳方法是什么。我正在制作一个具有以下用户模式的电影站点:

let UserSchema = new mongoose.Schema({
    username: {
        type: String,
        index: true
    },
    password: {
        type: String
    },
    email: {
        type: String
    },
    name: {
        type: String
    },
    watchlist: [mongoose.Schema.Types.Mixed],
    seen: {
        like : {
            type: [mongoose.Schema.Types.Mixed]
        },
        dislike: {
            type: [mongoose.Schema.Types.Mixed]
        }
    },
});

当用户单击大拇指或大拇指向下的图标时,对象

{movieID: movieID, title: movieTitle, poster: moviePoster}

将被发送到seeed属性中的like或dislike数组。我将在我的EJS模板中使用此信息来确定是否已经看过电影,看过和喜欢过的电影,然后将不喜欢的按钮涂成灰色,如果看过和不喜欢的电影涂成灰色,则喜欢按钮。如果用户单击“清除”按钮,我还希望能够从看到的位置删除该项目。为了做到这一点,似乎我将不得不遍历两个数组以确定电影是否包含在其中,然后将其删除。似乎必须有一种更好的方法来做到这一点。我当时正在考虑使用movieID作为键来构造“可见”对象,如下所示:

seen: {
  '123': {
    movieID: '123',
    title: 'movieA',
    poster: 'movieA-poster.jpg',
    like: true
  }, 
  '456' : {
    movieID: '456',
    title: 'movieB',
    poster: 'movieB-poster.jpg',
    like: false
  }
}

但是当我尝试使用.findOne和此函数发送数据以进行查看时:

const movieObj = {
  id: req.body.movieID,
  title: req.body.movieTitle,
  poster_path: req.body.poster_path,
};

User.findOne({_id: req.user._id}, function(err, user) {
  if (err) {
    console.log(err);
  } else {

    user.seen[req.body.movieID] = movieObj;
    user.save(function(){});
  }
}

我仍然只是得到一个空对象给我。我将架构看到的对象更改为:

seen: { type: mongoose.Schema.Types.Mixed, default: {} }

并设置了{minimize:false},因为我读到猫鼬默认情况下不允许空对象。感谢有关我在做什么的任何指导,或者是否有更好的方法来有效地构建架构,以便轻松地将看过的电影添加到数据库中或从数据库中删除。

2 个答案:

答案 0 :(得分:1)

我认为猫鼬会在这里为您提供帮助。
只需阅读一下,您就会对它有个好主意。 这是一个带有示例的良好链接:

https://hashnode.com/post/how-do-i-successfully-populate-a-mongoose-schema-cj339r6kt004g5mk83ycujilq

答案 1 :(得分:1)

请查看此模型和查询,它们可以帮助您建立方案

1. 用户架构

let UserSchema = new mongoose.Schema({
    username: {
        type: String,
        index: true
    },
    password: {
        type: String
    },
    email: {
        type: String
    },
    name: {
        type: String
    },
    watchlist: [mongoose.Schema.Types.Mixed],
    like : [mongoose.Schema.Types.ObjectId], //remove
    deslike : [mongoose.Schema.Types.ObjectId], //remove
    seen : [{
    movieId : { type:  : mongoose.Schema.Types.ObjectId,  ref: 'Movie' },
    isStatus : {type : string} //Enum [like,dislike,'seen']
}]
})

2. 电影模式

let movieSchema = new mongoose.Schema({
    tile: {
    type: String
  },
  description: { type: String }
})

3。数据存储在两个表中

/ 用户 /

 {
        "_id" : ObjectId("5b5acaf0589ff6bfb5dd091f"),
"seen" : [ 
        {
            "movieId" : ObjectId("5b9e2544953b5f69683059d4"),
            "isStatud" : "like"
        }, 
        {
            "movieId" : ObjectId("5b9e2544953b5f69683059d6"),
            "isStatud" : "dislike"
        }, 
        {
            "movieId" : ObjectId("5b9e256d953b5f69683059ee"),
            "isStatud" : "seen"
        }
    ]
        "like" : [ 
            ObjectId("5b9e2544953b5f69683059d4"), 
            ObjectId("5b9e256d953b5f69683059ee")
        ],
        "deslike" : [ 
            ObjectId("5b9e2544953b5f69683059d6")
        ]
    }

/ 电影 /

{
    "_id" : ObjectId("5b9e2544953b5f69683059d4"),
    "title" : "movie1",
    "description" : "desc1"
}

{
    "_id" : ObjectId("5b9e2544953b5f69683059d6"),
    "title" : "movie2",
    "description" : "desc2"
}

{
    "_id" : ObjectId("5b9e256d953b5f69683059ee"),
    "title" : "movie3",
    "description" : "desc3"
}

查询以按电影吸引用户

/ 这工作正常且经过测试 /。

db.getCollection('user').aggregate([{
    $match : { _id : ObjectId("5b5acaf0589ff6bfb5dd091f") }
    },
    {$lookup : {
        from : 'movie',
        localField : 'like',
        foreignField : '_id',
        as : "likes"
        }},

        {$lookup : {
        from : 'movie',
        localField : 'deslike',
        foreignField : '_id',
        as : "deslikes"
        }}

    ])

/ 使用组查询 /

db.getCollection('user').aggregate([{
    $match : { _id : ObjectId("5b5acaf0589ff6bfb5dd091f") }
    },
    {$unwind : '$seen'},
    {$lookup : {
        from : 'movie',
        localField : 'seen.movieId',
        foreignField : '_id',
        as : "seen.movieData"
        }},
    {$unwind : '$seen.movieData'},
    { $group: { "_id": "$_id", 
              "name" : { "$first": "$name" }, //use same all other field of user
              "seen" : {"$push" : "$seen"}
               } ,
                }
    ])

请检查并让我知道任何帮助。