简体   繁体   中英

Big query in MongoDB with Mongoose

I have an User model defined. This model has two lists, one of the items the user has liked and the other one is of the items the user has disliked.
I need a list of the items that one User hasn't qualified (neither liked nor disliked) and the other users did. I'm using the Mongoose library for NodeJS and also the lodash(_) library, my code looks like this:

function itemsUserHasntQualified(var user){
  items = [];
  User.find().exec(function(err, users){
    for(var user_it: users){
      if(user_it != user){
        items.push(_.difference(user_it.tracks.liked, user_it.tracks.disliked, user.tracks.liked, user.tracks.disliked);
      }
    }
  });
}

This is the schema for the User :

var UserSchema = new Schema({
  name: String,
  username: {type: String, lowercase:true },
  email: { type: String, lowercase: true },
  role: {
    type: String,
    default: 'user'
  },
  hashedPassword: String,
  provider: String,
  salt: String,
  facebook: {},
  twitter: {},
  google: {},
  github: {},
  tracks: {
    liked: [{type:Schema.ObjectId, ref: "Track"}],
    disliked: [{type:Schema.ObjectId, ref: "Track"}],
    later: [{type:Schema.ObjectId, ref: "Track"}]
  }
});

But actually I'm feeling this is not the correct way of do it. Is there a simpler or more correct way of query this?

I'm not sure what classifies as correct , but you can at least run the bulk of the query in mongodb without returning the entire collection.

Mongoose Query#distinct which is db.collection.distinct() will return distinct array items and can be supplied a query.

User.distinct('tracks.disliked', { username: { $ne: username } })
User.distinct('tracks.liked', { username: { $ne: username } })

This will give you the arrays for liked and disliked , which you can then difference for a user.

UserSchema.methods.itemsUserHasntQualified = function () {
  var user = this
  var liked = User.distinct('tracks.liked', { username: { $ne: user.username } })
  var disliked = User.distinct('tracks.disliked', { username: { $ne: user.username } })

  Promise.all([liked, disliked]).then(function (results) {
    var all_ratings = _.union( results[0], results[1] )
    var users_ratings = _.union( user.tracks.liked, user.tracks.disliked )
    var missing = _.difference( users_ratings, all_ratings )
    return missing
  })
}

Depending on your access patterns, you might want to run this collection scan somewhere else, less frequently and cache the array results for use in itemsUserHasntQualified .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM