WordPress.org

Make WordPress Core

Opened 5 months ago

Last modified 3 months ago

#41287 new enhancement

Add AND query mode for taxonomy terms

Reported by: sebbb Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 4.8
Component: REST API Keywords: needs-patch needs-unit-tests
Focuses: Cc:

Description

I'm trying to query the Rest API to get only posts that contain a given set of tags. If, for example, I request the following from the Rest API:

/wp-json/wp/v2/posts?tags=41+50

I get posts that don't satisfy all the tags. For example, the first post returned in the JSON response has the tags 45, 38, 46, 42, 35, 50, 43, 36, 37, 75, 76. The post doesn't have the tag with ID 41, while the expected output would be only posts that satisfy all the provided tags.

It looks like behind the scenes the API uses an OR logic instead of the correct AND logic. It returns posts that contain at least one of the provided tags. I'm experiencing the same exact problem with categories as well.

I tried different versions of the above URL, but I'm facing the same issue:

/wp-json/wp/v2/posts?tags=41&tags=50

/wp-json/wp/v2/posts?tags=41,50

Interestingly, tags_exclude seems to work perfectly and the following url correctly returns posts that have neither the tag ID 41 nor the tag ID 50:

/wp-json/wp/v2/posts?tags_exclude=41+50

Change History (8)

#1 @kadamwhite
5 months ago

It looks like behind the scenes the API uses an OR logic instead of the correct AND logic.

Unfortunately this is exactly what is happening; the API does not currently support AND logic for querying records by taxonomy ID. We tracked this problem in our old GitHub repository as issue # 2768, but it doesn't look like that issue has made it here into trac -- thanks for opening the ticket.

We should have a way to query posts by taxonomy terms using an AND relation. I agree that the current behavior is highly unintuitive.

@rmccue may be able to clarify but I'd also comment that, as far as I understand it, id1+id2 or id1,id2 are both just proxies for the ?tags=id1&tags=id2 syntax, so there isn't a clear way to distinguish between AND or OR without introducing a new API query parameter.

#2 follow-up: @LewisCowles
5 months ago

Is there a way for the existing OR functionality / bug to be provided via API endpoint or parameter to the existing endpoint to toggle between AND / OR?

I'm thinking it could be helpful for certain situations (find all posts in EITHER taxonomy X or Y, rather than find all posts in ONLY taxonomy X and Y).

Also does it only affect tags?

Last edited 5 months ago by LewisCowles (previous) (diff)

#3 in reply to: ↑ 2 @sebbb
5 months ago

Replying to LewisCowles:

Also does it only affect tags?

It seems to be affecting categories as well.

#4 @LewisCowles
5 months ago

Thanks. The reason I ask is that I'm going to borrow that bugged code. For a while now I've been thinking about provisioning a way for users to de-select taxonomy data to hide things they don't want. (Imagine if you could choose to hide unwanted political commentary).

It would require some work on author and editor part, but it's the first time I've seen something pre-built and will save me a few rainy days.

#5 @jnylen0
5 months ago

  • Keywords needs-patch needs-unit-tests added
  • Milestone changed from Awaiting Review to Future Release
  • Summary changed from Getting posts that belong to multiple tags or categories to Add AND query mode for taxonomy terms
  • Type changed from defect (bug) to enhancement

This is intended behavior, not a bug. I would expect "filter the posts list to posts that include tags 41,50" to return all posts that match any of these tags. "exclude tags 41,50" should not match any of those posts. If tags used AND, but exclude_tags used OR, this would be less consistent.

Having said that, adding an AND query mode would be a nice enhancement. The solution will likely look similar to the approach discussed in #39494.

For now, it should be possible to use the rest_{$this->post_type}_query filter -- possibly combined with register_rest_field (docs) -- to make this functionality work in a plugin.

Last edited 5 months ago by jnylen0 (previous) (diff)

This ticket was mentioned in Slack in #core-restapi by kadamwhite. View the logs.


5 months ago

#7 @sebbb
3 months ago

It's too bad that this is not considered a bug 😢.

I would think that the alternate syntax using + (i.e.: tags=41+50) implies that only the posts that have both tag 41 and tag 50 should be returned.

I'm working on an app that needs that feature, so I'll certainly look into a DIY solution in the meantime.

Unfortunately I don't have any PHP, WordPress or API design background myself, so I wouldn't be able to create the patch.

#8 @dd32
3 months ago

#41908 was marked as a duplicate.

Note: See TracTickets for help on using tickets.