I would like to show fivestar in Search Api solr search but at the moment with views, I am not able to. How can this be implemented?

Comments

BeaPower’s picture

anyone?

Shadlington’s picture

You can display it in search results by using the entity row style (rather than fields) but to be able to sort/filter/facet/etc. fivestar would need to implement the entity api. I'm really not aware of how much work that would be at all.

BeaPower’s picture

Thanks works nicely with display suite.

ericduran’s picture

Status: Active » Fixed

Closing this issue as it's been resolved as per comment #3.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

stopshinal’s picture

Status: Closed (fixed) » Active

"fivestar would need to implement the entity api. I'm really not aware of how much work that would be at all." I would like to reopen this to address the integration of fivestar with entity - which would hopefully allow it to be access by search api (and possibly rules too? two birds one stone!?)

Shadlington’s picture

Title: How to add fivestar to Search Api Solr Search? » Integrate with Entity API

Renaming as this is what you are asking for now.

ericduran’s picture

Status: Active » Closed (won't fix)

Fivestar would never integrated with Entity API.

I don't see whats wrong with the fields. Ideally they'll be a field module that would allow any fields to be used with the search.

But right now based on the title this will never happened. Sorry.

Patches are always welcome if it helps solve the actual issue but just a patch integrating with entity api probably wont get in. Also I don't quiet see why fivestar needs to integrate with entity api.

I'm marking this ticket as Will not fix. Feel free to re-open if this is indeed needed, but I'm a bit doubtful :(

zambrey’s picture

Component: Documentation » Code
Status: Closed (won't fix) » Needs review
StatusFileSize
new1.53 KB

Actually you have added Entity API support by adding integration with Microdata:

function fivestar_property_info_callback(&$info, $entity_type, $field, $instance, $field_type) {
  $name = $field['field_name'];
  $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$name];

  $property['property info'] = array(
    'average_rating' => array(
      'label' => t('Average Rating'),
      'type' => 'text',
      'microdata' => TRUE,
    ),
    'user_rating' => array(
      'label' => t('User\'s Rating'),
      'type' => 'text',
      'microdata' => TRUE,
    ),
  );
}

So with this code fivestar can be used for example to index average ratings using Search API.
However current code is incomplete because fivestar defines properties but doesn't provide method to return proper value of them. To check this functionality you can use simple entity wrapper (with loaded $node which has field named 'field_vote'):

$item = entity_metadata_wrapper('node', $node);
$rating = $item->field_vote->average_rating->value();
// print or dpm() $rating which should display average rating of this node.

Default Entity API method can't be used here because values of fivestar field are different than defined in the schema. To make long story short we must define custom function.
Here's the initial patch.

Fidelix’s picture

This is badly needed.

Zahak’s picture

Need it too. If not possible to (for instance) sort search result by average rating, then the rating itself is of no use. Sure it's nice to show when someone looks at the node, but the idea (at least for me) is to aid people when searching.

epieddy’s picture

Subscribing

ericduran’s picture

Yea, this issue is not clear to me as to why we need this.

Also the microdata stuff was cleaned up. I'm not sure this still applies. I'll see.

ericduran’s picture

#9: fivestar-entity-api-1256572-9.patch queued for re-testing.

Zahak’s picture

While #9 solves the issue with no values at all, there still are problems since it seems that it fetches values from field_data_field_fivestar_rating_rating, which only stores last value.

mysql> SELECT * FROM votingapi_vote WHERE entity_id=10;
+---------+-------------+-----------+-------+------------+------+-----+------------+---------------+
| vote_id | entity_type | entity_id | value | value_type | tag  | uid | timestamp  | vote_source   |
+---------+-------------+-----------+-------+------------+------+-----+------------+---------------+
|       6 | node        |        10 |    60 | percent    | vote |   4 | 1335445526 | 213.50.33.196 |
|      25 | node        |        10 |    60 | percent    | vote |   0 | 1340636755 | 10.104.230.1  |
|      26 | node        |        10 |    40 | percent    | vote |   0 | 1340636760 | 10.104.230.1  |
|      27 | node        |        10 |    60 | percent    | vote |   0 | 1340636762 | 10.104.230.1  |
|      35 | node        |        10 |   100 | percent    | vote |   3 | 1341400741 | 10.104.230.1  |
|      36 | node        |        10 |    60 | percent    | vote |   0 | 1341401219 | 10.104.230.1  |
|      37 | node        |        10 |    20 | percent    | vote |   0 | 1341401247 | 10.104.230.1  |
|      38 | node        |        10 |    60 | percent    | vote |   0 | 1341401266 | 10.104.230.1  |
|      39 | node        |        10 |    80 | percent    | vote |   0 | 1341401268 | 10.104.230.1  |
|      40 | node        |        10 |    80 | percent    | vote |   0 | 1341401269 | 10.104.230.1  |
|      41 | node        |        10 |    80 | percent    | vote |   0 | 1341401270 | 10.104.230.1  |
|      42 | node        |        10 |    80 | percent    | vote |   0 | 1341401271 | 10.104.230.1  |
|      43 | node        |        10 |    80 | percent    | vote |   0 | 1341401272 | 10.104.230.1  |
|      44 | node        |        10 |   100 | percent    | vote |   0 | 1341401273 | 10.104.230.1  |
|      45 | node        |        10 |   100 | percent    | vote |   0 | 1341401274 | 10.104.230.1  |
|      46 | node        |        10 |   100 | percent    | vote |   0 | 1341401275 | 10.104.230.1  |
|      47 | node        |        10 |    80 | percent    | vote |   0 | 1341401276 | 10.104.230.1  |
+---------+-------------+-----------+-------+------------+------+-----+------------+---------------+
17 rows in set (0.00 sec)

mysql> SELECT entity_type, bundle, entity_id, field_fivestar_rating_rating, field_fivestar_rating_target FROM field_data_field_fivestar_rating where entity_id=10;
+-------------+--------+-----------+------------------------------+------------------------------+
| entity_type | bundle | entity_id | field_fivestar_rating_rating | field_fivestar_rating_target |
+-------------+--------+-----------+------------------------------+------------------------------+
| node        | recipe |        10 |                           80 |                         NULL |
+-------------+--------+-----------+------------------------------+------------------------------+
1 row in set (0.00 sec)

Zahak’s picture

StatusFileSize
new1.79 KB

New patch that works in my project:

Energyblazar’s picture

Nice me gona try it out...

brunorios1’s picture

i'm trying to index an average rating field to use as a sort option in my search (via search_api_sorts module) but i'm getting NULL in the search_api_db table (screenshot attached)...

the question is: do we need Entity Api integration to make the average rating fields indexed by search_api???

thank you!

Zahak’s picture

Yes. Patch above should solve issue.

brunorios1’s picture

i have two fields:

one field in "node" [field_average_rating]
one field in "comment" [field_comment_rating]

the [field_average_rating] displays the average results of the comment votes.
i followed the steps in http://drupal.org/node/1274426#comment-4975152

works perfectly in the frontend, the widget displays the average value correctly.

now i'm trying to index the [field_average_rating] without success (#18).

so i looked in the database and the [field_data_field_average_rating] table is always empty...
this is "working as designed"? the [field_average_rating] should save the average value in the db after every vote or just calculate and display?

i applied the patch in #16 but don't work for me.

thanks!

EDIT:
the correct is to use the same field of the content type ([field_average_rating]) in the comments too.
thanks.

chirhotec’s picture

@Zahak

Could you explain how to get the patch working to sort search results by average rating?

I've added the patch, gone to my search index, added the "Rating >> Average Score" field, and re-indexed.

I get the following error several times:

Notice: Undefined offset: 0 in _fivestar_field_property_values() (line 752 of /home/vire/httpdocs/sites/all/modules/fivestar/includes/fivestar.field.inc).

First, it occurs when re-indexing, once for every node that has at least one prior vote
Second, it occurs on the search View, twice for every node that has at least one prior vote.

The table search_api_db__field_rating_average_rating is empty

chirhotec’s picture

StatusFileSize
new1.84 KB

Ah, simple fix to the above problem. Basically, I wasn't using the default "vote" tag for that field. I updated the patch from #16 to use the $field['settings']['axis'] to get the correct tag.

Even after that, the error would still occur (once on indexing, twice on results) for every node that had received a vote, and then that vote was cancelled. So, I modified it so that if the query ever comes back blank, it returns 0.

But, in the end, I'm still not able to sort by the average vote, just display it. My search view is based on the Search Index, not Node type. Any ideas?

EDIT: I was able to get it to work with views sort. Not sure what did the trick, but I know in the process I disabled / re-enabled the Rating >> Average Rating on the Search Index Fields, and re-indexed afterward. At some point it showed up in the sort options on the view page

e-fee’s picture

Here's one more person who would love to see this integrated!
Customer demanded a search result page, ordered by Fivestar ratings, was told that it is possible, and here I am now, left with what other people promised and prepared before I got my current job ... wow, great! My boss is even cursing Drupal and planning to use a different CMS in the future, ONLY because of stuff like this!

Tried the patches, none of them worked for me. All I can get is to display a number as a field, no filtering, no sorting. Plus, I would love to reuse the nice Display Suite based view mode for my rendered entity, instead of displaying fields.

Ok, so far I'm not too deep into Entity API, it's integration with Search API and Views and possible difficulties or incompatibilies.

But as some more people posted the very same problem into several issues over quite some time, this

Also I don't quiet see why fivestar needs to integrate with entity api.

sounds to be a bit questionable to me. I think one goal for modules should be that they do integrate just the way they're expected to do, so there you have your reason - this would make the life of developers and site-builders a whole lot easier. Fivestar has fields I can to a Search API index, Fivestar has fields I can show via Display Suite, I can also use them with a view of regular nodes, I can get the average rating value ... but for whatever reason, there should be no way to make the field available for sorting in Views???

I worship all the hard work people put into their modules - and as they've built them, for them it would be a lot easier to create a workaround than for other people who see the code for the first time in their lives.
But it is really hard if something doesn't work as everybody expects!

Fidelix’s picture

@e-fee, it doesn't work as everybody expects because noone went there and worked on it and contributed it back.

You can solve this manually if you have good PHP and know how to use the "Search API" API. It's a matter of constructing a custom field and providing sane data to your backend.

The same for views.

chirhotec’s picture

@e-fee:

What single value are you seeing?

Here are the steps I used to get it (semi) working:
1. Apply patch
2. In Search Api, add Rating field
2.a. Enable Rating >> Average Rating, as a Decimal Value
2.b Re-index
3. In you Search Index View...
3.a Add field "Indexed Node: Rating"- this should give you the Fivestar display in your view
3.b Add field "Rating: Average Rating (indexed)" - (check "exclude from display" after you are done testing it out)
3.c Add sort "Rating: Average Rating (indexed)" - check descending (assuming you want highest ratings first)

@all

The one problem I am having now is that if a user votes, it doesn't trigger a re-index. So, the search results get outdated quickly (and look odd if you only have a few votes, like I do on my test site).

brunorios1’s picture

@chirhotec,

have you tested with search_api_sorts?

thanks!

chirhotec’s picture

I have tested it with search_api_sorts and it didn't work. The problem is the same: The sorting is based on the Average Rating as stored when the item was indexed. When votes are added, deleted or changed, it doesn't trigger a re-index.

Here's a hack to fix this, but its ugly. Basically, on vote submission it triggers the search api to mark the associated entity that it needs to be re-indexed (if search api exists and is enabled, and if the vote is different). The item will be re-indexed based on your Search Index settings (either immediately, if items are set to be immediately indexed, or on the next cron batch).

in fivestar.module....

function _fivestar_cast_vote($entity_type, $id, $value, $tag = NULL, $uid = NULL, $skip_validation = FALSE) {
  global $user;
  $tag = empty($tag) ? 'vote' : $tag;
  $uid = isset($uid) ? $uid : $user->uid;
  // Bail out if the user's trying to vote on an invalid object.
  if (!$skip_validation && !fivestar_validate_target($entity_type, $id, $tag, $uid)) {
    return array();
  }
  // Sanity-check the incoming values.
  if (is_numeric($id) && is_numeric($value)) {
    if ($value > 100) {
      $value = 100;
    }

    // Get the user's current vote.
    $criteria = array('entity_type' => $entity_type, 'entity_id' => $id, 'tag' => $tag, 'uid' => $uid);
    // Get the unique identifier for the user (IP Address if anonymous).
    $user_criteria = votingapi_current_user_identifier();
    $user_votes = votingapi_select_votes($criteria + $user_criteria);

    // ------------------------------ SEARCH API RE-INDEXING HACK --------------------
    // if vote has changed, mark it for re-indexing in search api
    if (module_exists('search_api') && $value != $user_votes[0]['value']) {
      search_api_track_item_change($entity_type, array($id));
    }
    // ---------------------------- END SEARCH API RE-INDEXING HACK ------------------
    
    if ($value == 0) {
      votingapi_delete_votes($user_votes);
    }
    else {
      $votes = $criteria += array('value' => $value);
      votingapi_set_votes($votes);
    }

    // Moving the calculationg after saving/deleting the vote but before getting the votes.
    votingapi_recalculate_results($entity_type, $id);    
    return fivestar_get_votes($entity_type, $id, $tag, $uid);
  }
}

But again, its an ugly hack. Ideally, if the only thing necessary to integrate fivestar with search api, is to integrate it with entity API, then this shouldn't be necessary. You'd think search api would recognize it needs to re-index items if their indexed fields change values, not just on a whole entity update. But I don't know enough about Search API or Entity API to know how to properly fix this issue.

brunorios1’s picture

@chirhotec,
I think that the search api don't automatically recognize the fields changes, so, your hack is not ugly.

Your approach seems the right way to do the rating index updates, according to the comment the creator of search_api_sorts did on my issue in another module with the same needs: http://drupal.org/node/1728482#comment-6352740

By the way, the Radioactivity field is not very useful for Search API: you would need to re-index the node EVERY time the radio-activity changes. Search API will not know when Radioactivity has changed, until it re-indexes all those nodes. So whenever radioactivity changes, you need to add a hook to update the {search_api_item} table... Which is probably very resource intensive on large sites with a lot of radioactive nodes, you won't be able to use it.

chirhotec’s picture

That may be the case, but the question is still up for discussion: what is the reasonable expectation on module developers to integrate with these other modules? I think having most modules, including Fivestar, integrate with Entity API is reasonable. But I don't think its reasonable to require them all to integrate with Search API, if Search API uses Entity API and Entity API has a mechanism that indicates when a field has changed. I'd say either Entity API needs such a mechanism, or Search API should have better integration with Entity API.

Of course, if we want change, there are probably better places to discuss this :D

brunorios1’s picture

@chirhotec,

i followed the "Creating a User Comment/Rating and Average Rating for a Content type" steps in http://drupal.org/node/1308114

i have a field that is only displayed (rated while viewing) in the content type with a "review" tag,
and the same field (rated while editing) in the comments with a voting target "parent node" and the same tag.

i applied your last patch but the search_api_db_commerce_display_index_field_rating_average stills displaying a NULL value.

did you tested this use case?

thanks!

rudiedirkx’s picture

If Search API had some kind of entity 'content changed' hook, fivestar should use that. Since it doesn't (it doesn't, right?) I don't consider @chirhotec's solution a hack. I like it a lot.

A new patch should combine these two things: index the actual value AND reindex appropriately.

eigentor’s picture

I bumped upon this as well in a project.
Has anybody an idea how much effort it would be to provide a clean implementation with Entity API?

mkolar’s picture

Issue summary: View changes
StatusFileSize
new1.86 KB

Hi,

i just discovered that there is problem with non-node entity...

Notice: Undefined property: Entity::$nid in _fivestar_field_property_values() (line 799 of /.../sites/all/modules/contrib/fivestar/includes/fivestar.field.inc).
Notice: Undefined offset: 0 in _fivestar_field_property_values() (line 804 of /.../sites/all/modules/contrib/fivestar/includes/fivestar.field.inc).

Here is better solution and it works for me.

semei’s picture

I encounter a similar problem:

Notice: Undefined property: Registration::$uid in _fivestar_allow_vote() (line 984 of DRUPAL7/sites/all/modules/fivestar/fivestar.module).
Notice: Undefined property: Registration::$uid in _fivestar_allow_vote() (line 986 of DRUPAL7/sites/all/modules/fivestar/fivestar.module).

I am using the Fivestar module in combination with the Registration module, and I want to be able to rate submitted registrations. A submitted registration has an associated $user_uid, but not a $uid. Maybe registration isn't following conventions here and there's nothing that Fivestar could do.

sja1’s picture

I'm run into this problem as well. Will test patch above. I also found someone wrote a module that purports to implement proper fivestar/entity_api integration: https://www.drupal.org/project/search_api_fivestar

The last commit was in 2013, but there's a comment from the developer in late 2014 that suggests this module is still working.

alexverb’s picture

Category: Support request » Feature request
Status: Needs review » Reviewed & tested by the community

Patch 33 works flawlessly for me. For nodes and other entities as well. Setting this as reviewed and tested.

monstrfolk’s picture

I am experiencing the same issue as #30.

I can make the patch work if I do the following.

Change the fivestar field to (rated while editing)
Edit the content, vote, and then save
Change the fivestar field to (rated while viewing)

Now the values are stored in the search index and is updated everytime a user leaves a comment and votes.

UPDATE:

This is how I solved the problem. Created a custom module with the following. What is does is sets an arbitrary rating value on for the node when created or updated. You can remove the updated part and put the code only in the insert function (I had pre-existing content that needed to be updated). For indexing with the search API, it seems that it skips over anything that is not stored in a fivestar database table. There needs to be at least one value stored in it.

The db_merge part of the code needs to be repeated for each fivestar rating field for a particular content type.

function mymodule_node_insert($node) {
if ($node->type == 'CONTENT TYPE') {
mymodule_node_update($node);
}
}

function mymodule_node_update($node) {
if ($node->type == 'CONTENT TYPE') {
db_merge('NAME OF FIVESTAR FIELD TABLE IN DATABASE')
->key(array('entity_id' => $node->nid, 'bundle' => 'business'))
->fields(array(
'entity_id' => $node->nid,
'revision_id' => $node->nid,
'NAME OF FIVESTAR FIELD COLUMIN IN TABLE' => 20,
'language' => 'und',
'delta' => 0,
'bundle' => 'business',
'entity_type' => 'CONTENT TYPE'
))
->execute();
}
}

alexverb’s picture

For me it also works great. I'm running it on production. Could we get this committed?

dbt102’s picture

Status: Reviewed & tested by the community » Needs review

Since the reviews on this have been sitting in the queue for +8 months, I'm resetting the status on it back to "needs review" only because I'd like someone to double-check that the patch is still OK, relevant, and needed.

monstrfolk’s picture

Status: Needs review » Reviewed & tested by the community

Disregard my comment #37. This works and the patch is good. Setting to RTBC unless anyone objects.

  • dbt102 committed 20e1ddc on 7.x-2.x authored by mkolar
    Issue #1256572 by chirhotec, Zahak, mkolar, zambrey, brunorios1, dbt102...
dbt102’s picture

thanks @monstrfolk

dbt102’s picture

Status: Reviewed & tested by the community » Fixed
dbt102’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.