【问题标题】:Most efficient structure of mongoose Schema最有效的mongoose Schema结构
【发布时间】:2019-02-20 10:45:47
【问题描述】:

我很好奇构建我的 mongoose Schema 的最佳方式是什么。我正在制作一个用户模式设置如下的电影网站:

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}

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

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},因为我读到猫鼬默认不允许空对象。感谢有关我做错了什么的任何指导,或者您是否有更好的方法来有效地构建架构以允许从数据库中轻松添加或删除看过的电影。

【问题讨论】:

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


【解决方案1】:

我认为 mongoose populate 会在这里为您提供帮助。
只需阅读它,您就会对它有一个很好的了解。 这是一个很好的示例链接:

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

【讨论】:

    【解决方案2】:

    请查看可以帮助您构建模式的模型和查询。

    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"}
                   } ,
                    }
        ])
    

    请检查并告诉我任何帮助。

    【讨论】:

    • 感谢您的回复。所以这是我的第三个想法,将电影列在看过的和喜欢或不喜欢的数组中。由于我基本上只是在复制数据,因此在数据库中两次列出该信息会导致任何速度或性能问题吗?
    • 是喜欢还是不喜欢默认的?
    • seen更新我的答案请检查
    猜你喜欢
    • 1970-01-01
    • 2021-05-06
    • 2015-02-06
    • 2020-09-15
    • 2012-12-24
    • 2021-08-27
    • 2023-03-14
    • 2017-03-09
    • 1970-01-01
    相关资源
    最近更新 更多