diff --git a/app/repositories/orient_db/learning_object_repository.rb b/app/repositories/orient_db/learning_object_repository.rb index 11a8e047124db9f01be36a384382b957bf3682b8..fba180810448f31eab2da116a1fd88b6115f23dc 100644 --- a/app/repositories/orient_db/learning_object_repository.rb +++ b/app/repositories/orient_db/learning_object_repository.rb @@ -3,6 +3,7 @@ module OrientDb include OrientDb::Methods::EdgeMethods include RepositoriesProxy + ## # Call this methods for increment the views number of a +learning_object+ # You are creating the 'views' relation between an +user+ and +learning_object+ @@ -10,12 +11,30 @@ module OrientDb # # Nothing is returned def increment_views(user, learning_object) + values = {date: sanitize_orientdb_values(Time.now)} + + # If doesn't exist edges from user and learning object, create it and increment attribute if !edge_exists? "Views", user.rid, learning_object.id - create_edge "Views", user.rid, learning_object.id + create_and_set_edge "Views", user.rid, learning_object.id, values learning_object.views = learning_object.views + 1 + # If exists, update the date property of view + else + edge = get_edges "Views", "in", learning_object.id + edge = edge.first + + puts edge + set_values_edge edge["@rid"], values end end + def download(user, learning_object) + download_edge_class = 'Downloads' + values = {date: sanitize_orientdb_values(Time.now)} + + create_and_set_edge download_edge_class, user.rid, learning_object.id, values + learning_object.downloads = learning_object.downloads + 1 + end + ## # Call this method checks if the +user+ has a like relation with +learning_object+ # This methods returns a boolean @@ -34,8 +53,12 @@ module OrientDb def like(user, learning_object) like_edge_class = 'Likes' + # If not liked, like and set date if !liked? user, learning_object - create_edge like_edge_class, user.rid, learning_object.id + # The properties of edge. In this case, only date for edge 'Likes' + values = {date: sanitize_orientdb_values(Time.now)} + + create_and_set_edge like_edge_class, user.rid, learning_object.id, values learning_object.likes = learning_object.likes + 1 end end @@ -266,20 +289,33 @@ module OrientDb get_in_edges_count "Views", learning_object.id end + def count_downloads(learning_object) + get_in_edges_count "Downloads", learning_object.id + end + def max_likes Rails.cache.fetch('max_likes', expires_in: 6.hours) do - max = connection.command 'SELECT max(in("Likes").size()) FROM LearningObject' - max["result"][0]["max"] + get_max_from_edge("Likes","in") end end def max_views Rails.cache.fetch('max_views', expires_in: 6.hours) do - max = connection.command 'SELECT max(in("Views").size()) FROM LearningObject' - max["result"][0]["max"] + get_max_from_edge("Views","in") + end + end + + def max_downloads + Rails.cache.fetch('max_downloads', expires_in: 6.hours) do + get_max_from_edge("Downloads","in") end end + def get_max_from_edge(edge_class, type) + max = connection.command 'SELECT max(#{type}("#{edge_class}").size()) FROM LearningObject' + max["result"][0]["max"] + end + private def accepted_properties diff --git a/app/workers/score_calculator_worker.rb b/app/workers/score_calculator_worker.rb index 308f6c824517a931a201d0ce257af4cb8f4a6866..67cf84bafbaf6e4130ab060e346e77545278571b 100644 --- a/app/workers/score_calculator_worker.rb +++ b/app/workers/score_calculator_worker.rb @@ -7,25 +7,35 @@ class ScoreCalculatorWorker object = learning_object_repository.find(rid) unless object.blank? - weights = {"thumbnail": 40, "likes": 20, "views": 10, "description": 30} + # Weights to score. Sum must be 1000 + weights = { + "thumbnail": 250, + "description": 150, + "likes": 250, + "views": 150, + "downloads":200 + } - score = 0 + score = 0 - # 40 points if it has thumbnail - score += weights[:thumbnail] unless object.thumbnail.blank? + # 250 points if it has thumbnail + score += weights[:thumbnail] unless object.thumbnail.empty? - # 1 point per like - likes = learning_object_repository.count_likes(object) - score += (likes / learning_object_repository.max_likes)*weights[:likes] unless likes < 1 + # 150 points if it has description + score += weights[:description] unless object.description.empty? - # 1 point per view - views = learning_object_repository.count_views(object) - score += (views / learning_object_repository.max_views)*weights[:views] unless views < 1 + # range to 250 points, for normalized likes ( maxLikes/actualLike => [0..1] ) + likes = learning_object_repository.count_likes(object) + score += (likes / learning_object_repository.max_likes)*weights[:likes] unless likes < 1 - # 30 points if it has description - score += weights[:description] unless object.description.blank? + # range to 200 points, for normalized views ( maxLikes/actualLike => [0..1] ) + views = learning_object_repository.count_views(object) + score += (views / learning_object_repository.max_views)*weights[:views] unless views < 1 - learning_object_repository.update_property(object, 'score', score) + downloads = learning_object_repository.count_downloads(object) + score += (downloads / learning_object_repository.max_downloads)*weights[:downloads] unless views < 1 + + learning_object_repository.update_property(object, 'score', score) end end end diff --git a/lib/orient_db/methods/edge_methods.rb b/lib/orient_db/methods/edge_methods.rb index 021dc9169707f5f0d0b335013aa3ef567327b72e..2f03e58b75fef03b81cba18b136a37175757e15d 100644 --- a/lib/orient_db/methods/edge_methods.rb +++ b/lib/orient_db/methods/edge_methods.rb @@ -23,6 +23,14 @@ module OrientDb connection.command "CREATE EDGE #{edge_class} FROM #{from_id} TO #{to_id}" end + def create_and_set_edge(edge_class, from_id, to_id, values={}) + query = "CREATE EDGE #{edge_class} FROM #{from_id} TO #{to_id} CONTENT #{values.to_json}" + + puts query + + connection.command query + end + def destroy_edge(edge_class, from_id, to_id) connection.command "DELETE EDGE #{edge_class} FROM #{from_id} TO #{to_id}" end @@ -31,6 +39,14 @@ module OrientDb connection.query sprintf("SELECT expand(%s('%s')) FROM %s", type, edge_class, vertex_id) end + def get_edges(edge_class, type, vertex_id) + connection.query sprintf("SELECT * FROM #{edge_class} WHERE #{type} = #{vertex_id}") + end + + def set_values_edge(edge_id, values={}) + connection.command "UPDATE #{edge_id} CONTENT #{values.to_json}" + end + def edge_exists?(edge_class, from_id, to_id) edge = connection.query sprintf("SELECT outE('%s') FROM %s WHERE out('%s') CONTAINS %s", edge_class, from_id, edge_class, to_id) !edge.empty?