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.