Query Sanity documents by matching IDs from user's array

7 replies
Last updated: Mar 23, 2022
Hey everyone! I have a project I'm working on for a clothing brand where users are able to add what they own to their "closet". I added a button to the product page that when clicked adds the PieceID to an array and stores the items in the users closet. The problem I'm facing is that when the user goes to their closet page I'd like to query/show the pieces they have based on what's in their array. Here's the code snippet I use to query for the pieces:
sanityClient.
          fetch(`*[_type == "piece"]{
              title,
              slug,
              pieceID,
              mainImage {
                  asset->{
                      _id,
                      url
                  },
                  alt
              },
          }`)
          .then((data) => setPieceData(data))
          .catch(console.error);

AI Update

Looking at your code, you're currently fetching ALL pieces from Sanity, but you need to filter them based on the pieceID values stored in your user's closet array. You'll want to use the in operator in GROQ to check if a piece's pieceID exists in your array.

Here's how to modify your query:

// Assuming you have an array of pieceIDs from the user's closet
const userClosetIds = ['id1', 'id2', 'id3']; // Your array of pieceIDs

sanityClient
  .fetch(`*[_type == "piece" && pieceID in $closetIds]{
    title,
    slug,
    pieceID,
    mainImage {
      asset->{
        _id,
        url
      },
      alt
    },
  }`, { closetIds: userClosetIds })
  .then((data) => setPieceData(data))
  .catch(console.error);

The key changes:

  1. Added the filter condition: && pieceID in $closetIds checks if the piece's pieceID exists in your array
  2. Used a parameter: $closetIds is passed as a parameter for security and performance
  3. Passed the parameter: The second argument to .fetch() contains your array of IDs

The in operator in GROQ checks if a value exists in an array, which is exactly what you need here. This will only return pieces whose pieceID matches one of the IDs in your user's closet array.

If your array is empty, the query will return no results (which is the correct behavior for an empty closet). Make sure your pieceID field in your Sanity schema matches the format of the IDs you're storing in the user's closet array.

Show original thread
7 replies
Hey! So the users are stored in MongoDB. In the database they have an array called pieces and whenever the button on the product page on the front end is clicked it adds the pieceID to the array pieces
Are the pieces in any way referencing a user, though? Or is it only in this array in MongoDB that it exists?
Yeah so the pieces themselves don't reference a user, but the user has a collection of pieces stored in MongoDB. Once the user visits their profile/closet I'd like to send a query to sanity for only the pieceIDs that are in the users array. Sorry if I'm confusing you 😅
No worries, just trying to figure out the approach here! Since Sanity isn't aware of which pieces belong to which users, you'll have to query MDB for the array of pieces for the user, then pass them in as params to your GROQ query. For example:
const query = `*[_type == "piece" && pieceId in $userPieces]{
              title,
              slug,
              pieceID,
              mainImage {
                  asset->{
                      _id,
                      url
                  },
                  alt
              },
          }`
const params = {
  userPieces: //insert your MDB array here
}

sanityClient.
          fetch(query, params)
          .then(setPieceData)
          .catch(console.error);
user M
THANK YOU! Ugh I love this community
Worked flawlessly
Glad to hear it!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?