Opened 31 hours ago
Last modified 16 hours ago
#65313 new enhancement
Extend `WP_Comment_Query` 'fields' parameter to support individual column names
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Comments | Keywords: | has-patch has-unit-tests |
| Focuses: | performance | Cc: |
Description
Background
WP_Comment_Query currently accepts only two values for fields:
''(default) — fullWP_Commentobjects.'ids'— comment IDs only.
This is asymmetric with WP_User_Query, which accepts any valid user column as fields (e.g. fields => 'user_email', or an array of column names), returning a flat or shaped result without hydrating WP_User objects.
A common pattern in plugins that build "discussion-style" features on top of comments is to ask "give me the distinct comment_post_IDs where comments match X" — for example, listing posts the current user has commented on, or listing
posts with comments tagged with a particular meta value. Today there are three options, none good:
- Use
fields => ''andarray_column( $query->comments, 'comment_post_ID' )— hydrates every comment object only to throw all but one field away. - Use
fields => 'ids'and thenget_comment( $id )->comment_post_IDin a loop — N+1 cache lookups, still O(comments). - Drop to raw SQL — works, but bypasses
WP_Comment_Query's filters, caching, and meta-query machinery.
Real-world example
The gp-translation-helpers plugin (translate.wordpress.org) was hydrating ~32K WP_Comment objects per page load for a heavy validator just to extract the distinct post IDs:
<?php $query = new WP_Comment_Query( array( 'meta_key' => 'locale', 'meta_value' => $locale_slug, 'user_id' => $user_id, ) ); $post_ids = array_unique( array_column( $query->comments, 'comment_post_ID' ) );
That call took ~6.6 s on the live database. The equivalent direct SQL returned the same 25,694 distinct post IDs in ~610 ms (an ~11× speedup), purely because it stopped hydrating comments. The plugin had to fall back to raw SQL
(PR #236) for this reason.
Proposal
Allow fields to accept any valid column name from the $wpdb->comments table, matching the WP_User_Query behaviour. At minimum, 'comment_post_ID', 'user_id', and 'comment_parent' are high-value projections.
Suggested API:
<?php // Returns array of post IDs. $post_ids = ( new WP_Comment_Query() )->query( array( 'meta_key' => 'locale', 'meta_value' => 'nl', 'user_id' => 42, 'fields' => 'comment_post_ID', ) ); // Optional: support array of column names, returning stdClass per row. $rows = ( new WP_Comment_Query() )->query( array( 'fields' => array( 'comment_ID', 'comment_post_ID', 'comment_date' ), ) );
Backwards compatibility
'ids' and '' (default) keep their current meaning; new column-name values are purely additive.
Related
- #28434 — original ticket that added the
fieldsparameter (closed/fixed, 2014).
This ticket was drafted with AI, and reviewed before submit
Change History (4)
This ticket was mentioned in PR #11934 on WordPress/wordpress-develop by @dd32.
30 hours ago
#1
- Keywords has-patch has-unit-tests added
This ticket was mentioned in PR #11935 on WordPress/wordpress-develop by @anupkankale.
29 hours ago
#2
…olumn names
- Accepts a single valid column name (e.g. 'comment_post_ID') and returns a flat array of scalar values
- Accepts an array of valid column names and returns stdClass objects per row
- Invalid column names fall back to full WP_Comment objects
- Existing 'ids' and (default) behaviour unchanged
- Follows the same pattern as WP_User_Query
Fixes https://core.trac.wordpress.org/ticket/65313
Trac ticket:
## Use of AI Tools
@westonruter commented on PR #11935:
16 hours ago
#4
Thanks for the PR, but I'm closing in favor of #11934 since it lacks coding standards issues while also including unit tests. If you have any suggestions for that PR, please add them there.
## Summary
Extends
WP_Comment_Query'sfieldsargument to accept:$wpdb->comments(e.g.'comment_post_ID') — returns a flat array of distinct values for that column.'col_a=>col_b'pair (e.g.'comment_ID=>comment_post_ID') — returns an associative array keyed by col_a's value with col_b's value as the entry, mirroring the'id=>parent'idiom inWP_QueryandWP_Term_Query.'ids'and''(default) are unchanged — the new behaviour is purely additive.## Why
Plugins that want "the distinct
comment_post_IDs matching X" have three options today, none good:fields => ''+array_column( $q->comments, 'comment_post_ID' )— hydrates every matched comment just to discard all but one field.fields => 'ids'+get_comment( $id )->comment_post_IDin a loop — N+1 cache lookups.In the gp-translation-helpers reference case in the Trac ticket, hydrating ~32K comments to extract distinct post IDs took ~6.6s; the equivalent raw SQL returned the same 25,694 IDs in ~610ms (~11x speedup, all of it from skipping hydration).
## API
// Distinct comment_post_IDs — replaces array_unique( wp_list_pluck( ... ) ). $post_ids = ( new WP_Comment_Query() )->query( array( 'meta_key' => 'locale', 'meta_value' => 'nl', 'user_id' => 42, 'fields' => 'comment_post_ID', ) ); // [ comment_ID => comment_post_ID ] map — same shape as WP_Query's 'id=>parent'. $by_id = ( new WP_Comment_Query() )->query( array( 'post_id' => $post_id, 'fields' => 'comment_ID=>comment_post_ID', ) );Column names must be passed in their exact case. The only exception is the
IDsuffix ofcomment_ID/comment_post_ID, which is accepted in any case (comment_id,comment_Id,comment_ID). Unknown columns fall through to the default behaviour (WP_Commentobjects), keeping the path forward-compatible.## Test plan
npm run test:php -- tests/phpunit/tests/comment/query.php— 166 tests / 489 assertions pass.npm run test:php -- --group comment— 540 tests / 1367 assertions pass (no regressions).'col_a=>col_b'map form returns associative array.IDsuffix on both sides of=>; strict case for non-IDcolumns.WP_Commentobjects.'ids'semantics unchanged.array()without a follow-up query.phpcs --standard=phpcs.xml.distclean on both changed files (only pre-existing warnings on untouched lines).🤖 Generated with Claude Code