Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

How to select only certain fields from a relationship in REST API?

default discord avatar
cambo50last year
27

Hello,



I have a REST API call and my working query looks like this:



const select: Where = {


id: true,


title: true,


contest: true,


createdAt: true,


status: true


}



however this returns every single field from the contest collection, and I'm only looking for a couple fields, like this:



const select: Where = {


id: true,


title: true,


contest: {


id: true,


title: true


},


createdAt: true,


status: true


}



How do I achieve this with the REST API? The second version doesn't work. Thank you for your time!



That's what a was worried about. Thank you!

  • default discord avatar
    6teloivlast year

    I think this is fine.how exactly is the second one failing?



    Does it error, or does it still return all fields?

  • default discord avatar
    cambo50last year

    The select clause in the request URL returns undefined:

  • default discord avatar
    6teloivlast year

    huh, that's odd.



    that in the console would suggest the client is requesting that URL, no? meaning something going wrong in URL construction?

  • default discord avatar
    cambo50last year

    oh my bad, that was a different issue. What that does is just not return anything from the contest collection





    And then this is results for the first query, with just "contest: true"



    Which is what I'd expect, just way too much data

  • default discord avatar
    6teloivlast year

    First, I think

    populate

    is the appropriate field instead of select,

    populate

    is meant for controlling how it works with relationship fields.

    https://payloadcms.com/docs/queries/select#populate

    Second, even with populate, I can't get it work either. So this may be a bug



    WAIT



    I got it lol



    specify in select which fields you want from your record in the collection/global you are querying.



    specify in populate what fields to fill in for ALL relationship to a certain collection

  • default discord avatar
    cambo50last year

    oh snap! With a REST query, that would be a seperate clause from the select, correct?



    oh, just had to scroll down the docs page 😆

  • default discord avatar
    6teloivlast year

    For example, say you have a

    homepage

    global, and a

    posts

    collection. The homepage global has 2 relationship fields to the

    posts

    collection,

    archive

    and

    highlightedPosts

    . The

    posts

    have a

    title

    fields.



    To get only

    highlightedPosts

    and only their

    title

    fields, the query would be:



    /api/globals/homepage?select[highlightedPosts]=true&populate[posts][title]=true
  • default discord avatar
    cambo50last year

    That worked! Thanks so much. My instinct was to use the related collection id (contest), but it needs to be the full collection name (contests)

  • default discord avatar
    6teloivlast year

    Glad I could help :)



    This also helps me as well lol, I'm probably gonna use this to improve data fetching in my app!



    Could you mark this as solved? Can help others searching for the same thing in the future

  • default discord avatar
    mirus.studiolast year

    Hey

    @187449099472076811

    @282259503062188033

    , I'm having a hard time using Local API to fetch only certain fields from a collection that has two nested collections inside, do you know how I could do this with Local API? 🥲



    I have "products" collection with a "variants" join field that links to "product-variants" collection. This "product-variants" collection has inside an upload field called "images" that is linked to "media" collection.



    If I do not select anything or select "variants", I do get all fields up until image urls. But I can't figure out how to select some fields from products, some from variants and some from media...



    If I add defaultPopulate on some fields in "media", I get full object with only those fields inside images, but once I add defaultPopulate on "product-variants", images array becomes empty 😐



    Any idea? 🙏

  • default discord avatar
    cambo50last year

    Can you show us what your payload.find call looks like?

  • default discord avatar
    mirus.studiolast year

    Just a normal find:



    const rawProduct = await payload.find({


    collection: "products",


    depth: 10,


    where: {


    slug: {


    equals: productSlug,


    },


    },


    });



    I've tried using both select and populate in many different ways (that typescript let me) and still could not get the result I want



    I can do this:



    const rawProduct = await payload.find({


    collection: "products",


    depth: 10,


    where: {


    slug: {


    equals: productSlug,


    },


    },


    select: {


    name: true,


    variants: true,


    }


    });



    And it correctly only shows name field for product, and full variants object up until image urls and such

  • default discord avatar
    cambo50last year

    Okay, and then add your populate object to the query



    Should look something like



    const rawProduct = await payload.find({


    collection: "products",


    depth: 10,


    where: {


    slug: {


    equals: productSlug,


    },


    },


    select: {


    name: true,


    variants: true,


    },


    populate: {


    product-variants: {


    images: true


    }


    }


    });

  • default discord avatar
    mirus.studiolast year

    If I do this:



    const rawProduct = await payload.find({


    collection: "products",


    depth: 10,


    where: {


    slug: {


    equals: productSlug,


    },


    },


    select: {


    name: true,


    variants: true,


    },


    populate: {


    "product-variants": {


    name: true,


    images: true,


    },


    },


    });



    Then images becomes an empty array, not even ids



    That's what is confusing me 🫤

  • default discord avatar
    cambo50last year

    But the name field of product-variants are returned?

  • default discord avatar
    mirus.studiolast year

    yes 😂

  • default discord avatar
    cambo50last year

    okay, so I'm wondering if the images are another nested object that needs to be defined in your populate object. Is the images field a relationship to another collection?

  • default discord avatar
    mirus.studiolast year

    Yeah, it is an upload field related to "media". But even if I add now:



    populate: {


    "product-variants": {


    name: true,


    images: true,


    },


    media: {


    sizes: true,


    },


    },




    It still returns an empty array for images field

  • default discord avatar
    cambo50last year

    I just tried to add an image to my populate object and I didn't even get the field returned at all. Hmmm

  • default discord avatar
    mirus.studiolast year

    That's even weirder hahahah



    I don't know if we're doing anything wrong but man, it shouldn't be that hard to do something that simple 🥲

  • default discord avatar
    cambo50last year

    It looks like you can't specify fields beyond the first nested collection. When I do this:



    const select = { id: true, title: true, contest: true, createdAt: true, status: true } const populate = { contests: { id: true, title: true, slug: true, publisher: true }, publishers: { id: true, title: true } }

    the submission->contest->publisher object contains every field in publisher rather than just the id and title

  • default discord avatar
    mirus.studiolast year

    hmmm, In my case, publishers would be just an empty array, not even full object



    With this:



    const rawProduct = await payload.find({ collection: "products", depth: 10, where: { slug: { equals: productSlug, }, }, select: { name: true, variants: true, }, populate: { "product-variants": { name: true, images: true, }, media: { sizes: true, }, }, });


    I get this:


    [ { "id": 35, "name": "Camiseta DIVERTIRSE NO LE HACE DAÑO A NADIE", "variants": { "docs": [ { "id": 19, "name": "Camiseta DIVERTIRSE NO LE HACE DAÑO A NADIE - l", "images": [] }, { "id": 18, "name": "Camiseta DIVERTIRSE NO LE HACE DAÑO A NADIE - m", "images": [] } ], "hasNextPage": false } } ]
  • default discord avatar
    cambo50last year

    And just to confirm, both of those variant documents DO have images linked to them in the database?

  • default discord avatar
    mirus.studiolast year

    Yeah 100%. If I do not set any select/populate full object is returned as deep as it can get showing all linked images

  • default discord avatar
    cambo50last year

    oh right, you said that. You got me stumped, I'm afraid

  • default discord avatar
    mirus.studiolast year

    No problem man, it is definitely something strange 🤔



    Maybe

    @423216344302092288

    knows the answer? 😂

  • default discord avatar
    ritsu0455last year

    To solve this it'd be best to open an issue with a reproduction if you think that there's a bug so it can be tracked.


    Also, if you're on an older version you should update, a similar (or the same) issue was fixed recently -

    https://github.com/payloadcms/payload/pull/9751
Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.