How to query on multiple content types

I have various Content Types that represent article pages on a site. For the sake of example, I’ll say they’re as follows:

StoryArticle
  slug
SlideShowArticle
  slug
NewsArticle
  slug

All of these types have a slug field. So when a user loads a page of the site, we need to take the slug and find the corresponding Content.

So for a page of http://www.example.com/articles/latest-news-article

I’d query the API with the following parameters:

fields.slug=latest-news-article

However, doing so requires, per the API docs, that a “content_type” be specified, and I can only provide a single content type.

When querying entries and using search filters based on fields or ordering by fields you must specify this parameter. You can only specify one value for content_type at a time.

Why can I only specify one value for content_type? I know this page could be one of 3 content types, and I’d like to search across all 3, not just one.

How do I work around this?

The way to solve this is with a common content type, maybe called Article, which has the fields common to all 3 of your article content types including the slug, and a single reference to a StoryArticle, SlideShowArticle, or NewsArticle (which should only have the specific content relating to a story, slideshow, or news piece).

That way you can have a single content type, Article, to search for the slug, but still get all the information specific to the particular article type.

Hey @jason1,

In general, it is possible to specify entries of multiple content types by specifying a search parameter on the lines of the following:

sys.contentType.sys.id[in]=[content_type1],[content_type2],...

As shown in the following example:

https://cdn.contentful.com/spaces/cfexampleapi/entries?access_token=b4c0n73n7fu1&sys.contentType.sys.id[in]=cat,dog

Reference link

However, the issue here is that each field is defined on the basis of a single content type.

That being the case, although your fields may have the same name across multiple content types, they will effectively be different entities, so it’s unfortunately not possible to search through the fields of different content types that you may have specified in your query.

So, as Charlie greatly explained, you may want to create a common content type.

Hope this helps :grinning:

1 Like

@charlie That’s a solve, but that means I’ll have to update my data model (in a way that’s really going to confuse things) AND it will affect the content editing experience just to work out an API limitation. That’s definitely not ideal.

1 Like

Hi there, one year later, is this still the case? I am using the .NET core api, and I’m not able to get that sys.contentType.sys.id query to work, it throws before making the query with the error that I need to set A content type id.

We are in the beginning of our project, and don’t have much content yet so I guess I could make a common entity and then link the “sub-entity” in via reference. Hows the performance doing that way?

Hi @ullmark,
Could you tell us how exactly you’re trying to structure your query?

@gabriel I actually got some additional requirements and ended up structuring it like @charlie suggested. Worked out nicely.

Glad to hear that. Let me know if you have any other questions :slight_smile:

As soon as I add another filter, the API rejects:
https://cdn.contentful.com/spaces/cfexampleapi/entries?access_token=b4c0n73n7fu1&sys.contentType.sys.id[in]=cat,dog&fields.name[equals]=Jake

{
  "sys": {
    "type": "Error",
    "id": "BadRequest"
  },
  "message": "A Content Type ID is required. When querying for Entries and involving fields you need to limit your query to a specific Content Type. Please send a Content Type ID (not the name) as the URI query parameter \"content_type\"",
  "requestId": "51634155-b410-4371-84e5-97a092337cfe"
}

If I want to add other fields in addition to sys.contentTypes, do I need to create a base model?

Is this still the case (one content type per API query)? I ended up making 5 queries for each content type, merging the results into 1 array and then finally ordering that array.

Each search does cost me 5 API calls so this isn’t ideal.

1 Like

Hey, have you tried the API call with sys data as parameter? https://cdn.contentful.com/spaces/{space_id}/environments/master/entries?sys.contentType.sys.id[in]=contentTypeA,contentTypeB

Can you try to add another filter, not just sys.contentType.sys.id[in] ?
As soon as I add another filter such as fields.name[equals], the API returns BadRequest @Alma

Hey there, it doesn’t work with fields.name[equals] parameter.

In the Content Delivery API documentation it reads:

Equality and inequality operators are not supported for text fields and you need to constrain search queries for fields with a content_type URI query parameter.

The error message of the API call also hints:

“message”: “A Content Type ID is required. When querying for Entries and involving fields you need to limit your query to a specific Content Type. Please send a Content Type ID (not the name) as the URI query parameter "content_type"”

@Alma Any chance this restriction will be addressed at some point?

I guess the root issue here is that I, and apparently others as well, want to have distinct content types. Having a common content type model works around the limitation here, but from an editor’s perspective it’s far from ideal. Content editors now need to know which fields to set and which ones to not set when authoring entries, instead of being given a distinct set based on their content type.

Being able to query on a common field across content types seems like the ideal approach here.

5 Likes

Is this problem solved with GraphQL? I can query an array of content types in one call…

{
   storyArticleCollection(where: { 
		slug: "dog"
  }) {
    items {
      ...
    }
  }
 slideShowArticleCollection(where: { 
		slug: "dog"
  }) {
    items {
      ...
    }
  }
  ...
}

Hi All,
Thanks for the detailed explanation on the limitation in querying common fields across multiple content types. I’m interested to know if there is any other solution available without altering Content model, at this moment?