Design
 Active
 

https://forum.xwiki.org/t/introducing-like-feature/7339/8
https://extensions.xwiki.org/xwiki/bin/view/Extension/Ratings%20API

Description

A Rating API is available since XWiki 6.4 (see Rating API), however this API suffers from several drawbacks:

  1. the API has been conceived to consider that the Ratings will be stored as xobjects: this is a bad design choice, the API should be agnostic about the way Ratings are stored, especially since storing data as xobject is not scalable
      2. a big part of the API is exposed and not internalized: this makes it difficult to evolve without breaking backward compatibility
      3. the API is entirely dedicated for Ratings of Page and currently only one instance of Rating can exist in a wiki, however there could be needs to allow in the same wiki ratings of Pages, Comments, custom XObjects, etc.

Moreover, until now the Rating app wasn't bundled in XWiki Standard, but it changes with the creation of Likes which now relies on the Ratings API. This also pushed for new needs, which is why we start this work now.

This design page aims at listing all the usecases we'd need for a Ratings API that could be used for various usages of Ratings (using it for Ratings pages, but also for Liking Page, comments, or Ratings comments, etc).
I will try in the following to provide information about what's already available and what is not.
One goal of the page is to help decide if we need a completely new module for rating API and discard the old one, or if we can refactor the existing one.

Use-Cases

  - UC1: Allow to handle multiple RatingsManager in an instance of XWiki with a dedicated scale for each one (e.g. a "RatingsPage" RatingsManager with a scale on 0 to 5, a "LikePage" RatingsManager with a scale on 0 to 1, etc) [not supported with original Rating API]
  - UC2: Allow to retrieve Ratings information for a specific RatingsManager instance with following information: entityreference rated, userreference who rates, actual note on the scale, date of rating, date of update of rating [partially supported: only for DocumentReference, without the update date and for one RatingManager]
  - UC3: Allow to store a Rating vote for a specific RatingsManager on a dedicated EntityReference: scale must be respected [supported for one RatingManager]
  - UC4: Allow to retrieve an average score of Ratings for a specific RatingsManager on a specific EntityReference: the average should be pre-computed for scalability reason [already supported for one RatingManager]
  - UC5: Allow to retrieve the full number of Ratings for a specific RatingsManager on a specific EntityReference: particularly useful when scale is [0,1] [not supported]
  - UC6: Allow to retrieve all Ratings of an user for a specific RatingsManager: query should be doable with pagination [supported for one RatingManager]
  - UC7: Allow to retrieve the Ratings based on a complex query on a specific RatingsManager: e.g. ratings of a user between 2 dates [not supported]
  - UC8: Send events when a Ratings is created / updated / deleted [only supported for update and for one RatingManager]
  - UC9: Allow to provide different storages for Ratings: e.g. Solr, Hibernate Mapping, etc [supported for storing as xobjects and in Solr and for one RatingManager]
  - UC10: Manage Ratings Rights for each instance of RatingsManager [not supported]
  - UC11: Compute a Users' reputation based on their vote and on the vote of the pages they authored [supported]
  - UC12: Allow to handle CRUD operations of a specific RatingsManager through a script service [supported only for one RatingManager]
  - UC13: It should be possible to migrate old Ratings information
  - UC14: Extension Repository should work with this new API
  - UC15: Allow to import/export Ratings informations
  - UC16: Supports handling Average Ratings as XObject

UC1: Allow to handle multiple RatingsManager in an instance of XWiki

This use case is about being able to create a new dedicated RatingManager for a specific purpose on XWiki just by calling a dedicated API.
This API should include:
  - an identifier for the RatingManager instance
  - the voting scale (e.g. [0,1] for a Like, [0,5] for actual Ratings)

The API might also include:
  - the Type of EntityReference to be voted for: Not sure about that one, since it could limit further usages.

This is currently not supported in existing Rating application.

UC2: Allow to retrieve Ratings information for a specific RatingsManager

For a given RatingManager instance, it should be possible to retrieve all Ratings with pagination for scalability.
Ratings information should be:
  - EntityReference of the element being voted for
  - UserReference of the user who performs the vote
  - vote: an integer in the scale of the RatingManager instance
  - createdDate: date of the first vote
  - updatedDate: date of the latest update of the vote
  - DocumentVersionReference: (if it applies) reference of the document reference version that contains the EntityReference
  - RatingManager ID
  - Rating ID
  - RatingManager scale

This is partially supported: not all information are available, the types are currently wrong (e.g. a DocumentReference is stored instead of an EntityReference) and it's only supported for one RatingManager.

UC3: Allow to store a Rating vote for a specific RatingsManager on a dedicated EntityReference

A given user should be able to vote for an EntityReference and store it using a specific RatingsManager instance.
If the user already voted for this EntityReference on the same RatingsManager instance, then his vote should be updated.
Note that maybe in the future we'd need a configuration to prevent updating a vote.

For some usecases (e.g. like) we can also have a configuration to simply delete the vote if it's set to the lower bound (0 for Like) (cf. UC5).

This is partially supported: only for rating a DocumentReference and on one RatingsManager.

UC4: Allow to retrieve an average score of Ratings for a specific RatingsManager on a specific EntityReference

It should be possible to compute for any EntityReference an average score of votes.
For scalability reason, this average score should be computed at each vote and stored permanently. 

The average score result should display information about its computation, basically we should obtain:
  - the average score computed (a double with all digits, not rounded)
  - the total number of ratings taken into accounts
  - the actual scale of the RatingsManager
  - the RatingsManager ID
  - the EntityReference
  - the hint of the method use to compute the average score (see below)

Note that in the Actual Rating API it's also possible to compute an Average Rating balanced by the reputation of the Author. (See UC11).

UC5: Allow to retrieve the full number of Ratings for a specific RatingsManager on a specific EntityReference

The idea here is to be able to have a count of all votes made for an EntityReference on a specific RatingsManager.
It could be particularly useful in case of Likes for example, when the Average rating doesn't really make any sense: in that case we'd want the total number of Likes, so the total number of votes if we consider that unlike is deleting the vote, and not putting the vote to 0.

Note that it could also be just the possibility to retrieve a count of Ratings matching some criteria (cf UC7).

This is not really supported right now.

UC6: Allow to retrieve all Ratings of an user for a specific RatingsManager

This can be seen as a specialization of UC7, but I wanted to have it since it's a really common UC.
The idea is just to be able to retrieve all votes a user has made for a specific RatingsManager (e.g. all Likes, all Rating pages, etc).

Information should be retrieved with pagination for scalability reason. 

UC7: Allow to retrieve the Ratings based on a complex query on a specific RatingsManager

The idea here is to allow developers to be able to perform complex queries on Ratings based on the stored information.
Use cases we could imagine for those queries:
  - being able to retrieve all Ratings of an user between 2 dates
  - being able to retrieve all Ratings made for a specific version of a page
  - being able to retrieve all Ratings above a given threshold
etc

The only evolving design I can think of right now for this, to avoid having something too complex, is an API with a Map of parameters.

This is currently not supported.

UC8: Send events when a Ratings is created / updated / deleted

Whenever a Ratings if created / updated / deleted an event should be send with the Rating information and the RatingsManager identifier.
Two usecases already exist for those events:
  - update of Average ratings
  - send a user notification 

This is only suppored for updating Ratings right now, and only for one RatingManager.

UC9: Allow to provide different storages for Ratings: e.g. Solr, Hibernate Mapping, etc

The way Ratings are stored can evolve over time, so we should be able to provide different storages for Ratings.
In the current implementation Ratings can be stored as XObjects or in Solr.
I propose to drop support of Ratings as XObjects since it's not scalable, but instead to allow storing in Hibernate with a dedicated mapping.

The question of chosing the Storage manager for ratings is open:
  - it could be an implementation choice only (e.g. using the component for Solr storage in Like implem)
  - or it could be an Admin choice with a configuration, in which case this configuration could be for any RatingManager instance or for a dedicated one (e.g. storing in Solr for Like and in Hibernate for Ratings)

Moreover, does this change apply at runtime or does it need a restart? And what about allowing a Migration of data between 2 stores? 

Right now this is supported in current implementation with a choice to be made by Admin. It's possible to change the Store at runtime, but there's no migration proposed.

UC10: Manage Ratings Rights for each instance of RatingsManager

Performing a Rating on an element might be subject of a dedicated Right. This is the case for Like for example, where we have a dedicated Right for it.
We can imagine that any RatingsManager instance could have its associated Right, or that we manage globally Rating rights. 

This is currently not supported by Rating API.

UC11: Compute a Users' reputation based on their vote and on the vote of the pages they authored

Current Rating implementation allows to compute a Score about a User:
  - he gains points when performing a vote
  - he gains points when being voted for

From what I understand this reputation is mainly used to ponderate the Average Score.
I'm actually not sure if we really need such UC, from what I see it's available in Ratings API but not directly used in Ratings application.

UC12: Allow to handle CRUD operations of a specific RatingsManager through a script service

The main purpose of the Rating API is to be used in XWiki UI, so we'd need to be able to handle all CRUD operations on Ratings (and most of the API presented here) in a Script service just by specifying the identifier of the RatingsManager to use. 

UC13: It should be possible to migrate old Ratings information

This design pages is about proposing a new API for Ratings, so we should provide a way for migration the old Ratings information to be used in the new API.

UC14: Extension Repository should work with this new API

The Extension Repository apparently works in few places directly with the old Ratings XClasses, we need to ensure to refactor it so it works directly with the new API.

UC15: Allow to import/export Ratings information

We should be able to export a set of ratings information and to reimport them in a new wiki without needing to move an entire Solr core.

UC16: Supports handling Average Ratings as XObject

Some other extensions are directly using Average Ratings XObjects to provide augmented information in search etc: we should allow to keep using xobject for Average Ratings for those usecases.


 

Tags:
    

Get Connected