I was attempting to group by a field value and count the node IDs. However I found that all field columns are grouped, including entity_id, which means I am in effect grouping by node ID in addition to counting, which is definitely not what I wanted to do.
Here's the query generated and the view (which requires a field_country):
SELECT field_data_field_country.entity_id AS field_data_field_country_entity_id, field_data_field_country.etid AS field_data_field_country_etid, field_data_field_country.delta AS field_data_field_country_delta, field_data_field_country.language AS field_data_field_country_language, field_data_field_country.field_country_value AS field_data_field_country_field_country_value, field_data_field_country.field_country_format AS field_data_field_country_field_country_format, field_data_field_country.revision_id AS field_data_field_country_revision_id, field_data_field_country.bundle AS field_data_field_country_bundle, COUNT(node.nid) AS nid FROM {node} node LEFT JOIN {field_data_field_country} field_data_field_country ON node.nid = field_data_field_country.entity_id AND (field_data_field_country.etid = :views_join_condition_0 AND field_data_field_country.deleted = :views_join_condition_1) GROUP BY field_data_field_country_entity_id, field_data_field_country_etid, field_data_field_country_delta, field_data_field_country_language, field_data_field_country_field_country_value, field_data_field_country_field_country_format, field_data_field_country_revision_id, field_data_field_country_bundle LIMIT 10 OFFSET 0
$view = new view;
$view->name = 'test_group_by_field';
$view->description = '';
$view->tag = '';
$view->base_table = 'node';
$view->api_version = '3.0-alpha1';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
/* Display: Defaults */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->display->display_options['group_by'] = TRUE;
$handler->display->display_options['access']['type'] = 'none';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Fields: field_country */
$handler->display->display_options['fields']['entity_id']['id'] = 'entity_id';
$handler->display->display_options['fields']['entity_id']['table'] = 'field_data_field_country';
$handler->display->display_options['fields']['entity_id']['field'] = 'entity_id';
$handler->display->display_options['fields']['entity_id']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['entity_id']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['entity_id']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['entity_id']['alter']['trim'] = 0;
$handler->display->display_options['fields']['entity_id']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['entity_id']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['entity_id']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['entity_id']['alter']['html'] = 0;
$handler->display->display_options['fields']['entity_id']['element_label_colon'] = 1;
$handler->display->display_options['fields']['entity_id']['element_default_classes'] = 1;
$handler->display->display_options['fields']['entity_id']['hide_empty'] = 0;
$handler->display->display_options['fields']['entity_id']['empty_zero'] = 0;
$handler->display->display_options['fields']['entity_id']['click_sort_column'] = 'value';
/* Field: Node: Nid */
$handler->display->display_options['fields']['nid']['id'] = 'nid';
$handler->display->display_options['fields']['nid']['table'] = 'node';
$handler->display->display_options['fields']['nid']['field'] = 'nid';
$handler->display->display_options['fields']['nid']['group_type'] = 'count';
$handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['nid']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['nid']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['nid']['alter']['trim'] = 0;
$handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1;
$handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1;
$handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['nid']['alter']['html'] = 0;
$handler->display->display_options['fields']['nid']['element_label_colon'] = 1;
$handler->display->display_options['fields']['nid']['element_default_classes'] = 1;
$handler->display->display_options['fields']['nid']['hide_empty'] = 0;
$handler->display->display_options['fields']['nid']['empty_zero'] = 0;
$translatables['test_group_by_field'] = array(
t('Defaults'),
t('more'),
t('Apply'),
t('Reset'),
t('Sort By'),
t('Asc'),
t('Desc'),
t('Items per page'),
t('Offset'),
t('field_country'),
t('Nid'),
);
Comments
Comment #1
dawehnerWhat would be required here is to allow to select the raw data column in the field handler.
Currently there is a option for the database-value for clicksort but we could extend it to a general raw data column which is used on groupby, too.
This raw value has to be set to $this->real_field and will automatically be used by views_handler_field_group_by_numeric
Comment #2
bojanz commentedThat setting should probably be separate from the click sort column setting, someone might want to click sort on one, and group on another column...
We could group them in a fieldset though.
Comment #3
dawehnerThis issue has to wait on #1002744: Use entity_load for fieldapi field handlers
Comment #4
bojanz commentedAlso required: #1002764: Refactor the grouping code so that it can be extended.
Comment #5
solotandem commentedIs the attached patch heading in the right direction (with some polish as it is hard-coded for a pager view of the default display)? It works with a single value "field" but has not been tested with a multi-value field.
As comment #4 alludes to refactoring the grouping code, this should probably go in a file specific to field API, e.g. views_handler_field_field.inc.
Comment #6
bojanz commentedThat looks very good.
Definitely something we can do without waiting for the refactoring (which is not that big of a priority in light of other issues).
Awesome!
Comment #7
dawehnerLet's fix it first in 6.x-3.x
What i would really like to see is a possibility to alter the query out of the field handler.
The groupby_field handler could perhaps store other field handler and execute a certain function like query_groupby.
Comment #8
solotandem commentedThe attached patch for 7.x-3.x-dev attacks the problem at the source, adding a parameter to the 'additional fields' items in the field data. This parameter is passed to views_plugin_query_default->addField() and saved in the fields array where it can be utilized in views_plugin_query_default->compile_fields() to properly assemble the $non_aggregates list.
The patch only changes 6 lines of code. Unlike the previous patch, it should work regardless of the view or display plugin. It works with a single value "field" but has not been tested with a multi-value field.
If this makes sense, hopefully a similar approach can be utilized in 6.x-3.x branch.
My hunch is there are other "additional" fields that warrant the same treatment, e.g. those added to node, user, etc. and a @todo to that effect is included in the patch.
Comment #9
klaus66 commentedI think it is important to fix it, because it is a basic functionality.
e.g.
When I have a field with multiple values (like images) and the node can have 0 to 5 images, then it is the only way to group the images together and show only one row in the resultset for this node and not so much rows how images are there.
Comment #10
dawehner@solotandem
I general it would be cool if you could summarize what you talked with merlinofchaos in the irc :) Then this thing has a better documentation. THANKS!
Comment #11
solotandem commentedThe attached patch takes a different approach to enabling grouping with "field API" fields. It 1) conditionally adds form items to the group settings form and 2) takes advantage of the "use_group_by" parameter passed to query() methods (but not used by them, as the method signatures did not include it) to add fields to the query. As a simplification, the bundle column was moved to the regular "additional fields" code, leaving revision_id as the only odd man out. By default, only the specified "group column" is included in the query, but the user can specify certain other entity columns ('bundle', 'language', 'entity_type') to include and group on. As before, the additional columns do not result in items added to the display.
Last Friday in IRC, merlinofchaos and I agreed on the following points regarding the "field API" fields:
- grouping is a useful feature,
- when grouping applies, entities are not being retrieved, but rather collective (or grouped) information about entities is being retrieved
- including all the extra columns for an entity inhibits/prevents grouping, and
- therefore the views query should not include the extra entity columns (not requested by the user)
The documentation for field_view_field() indicates not all of the entity columns are necessary to rendering. And the code in the attached patch (as well as the previous one) also demonstrates/confirms this.
Comment #12
bojanz commentedMade a quick peek.
'und' should be LANGUAGE_NONE, but after #1006176: Add support for field based translation lands, we can no longer assume that.
Yes, we need the full "entity-like" object in order for the whole thing to work, see #987478: Field language is not properly handled.
How is all this affected by bringing back entity_load?
Comment #13
klaus66 commentedThe groupby works for me now (dev versions from 04 Jan 2011)
Comment #14
dawehnerOkay here is a new version.
Adressed the issues from #12
Basically it moved quite some stuff to the handlers. This makes all much easier and clean.
Comment #15
solotandem commentedAfter discussion in IRC with @dereine, the attached patch:
- moves the "if ($use_groupby) {}" in views_handler_field_field::add_additional_fields() to views_handler_field_field::query()
- eliminates views_handler_field_field::add_additional_fields()
- passes $fields to views_handler_field::add_additional_fields()
This eliminates a method and still keeps the field api code together.
Comment #16
solotandem commentedClean up code involving revision_id; eliminate switch block.
Comment #17
dawehner* Using a body and image field in both orders works fine.
* Formatters are working fine
* Groupby is working fine
What does not work but is currently unrelated to this issue is aggregate by the fieldapi field.
Fixed an issue with storing the group_type
Comment #18
dawehnerRemoved the todo's they are tackled.
Comment #19
solotandem commentedRemove 2 @todos.
Comment #20
dawehnerCommited to the 7.x branch. Thanks to everyone who worked on this issue.