How to query a multi-reference field in a collection in Velo

Hi all! I have a fairly simple challenge that I just can’t figure out. The challenge is querying a collection that has two fields and one of the fields is of a multi-reference type.

The collection is called Likes and it stores Member IDs in one column and Guide IDs in the second column. Guide IDs is the column that is of a multi-reference type. Here’s a screenshot of the collection as an example:

I’m looking to create a simple query that checks if a certain user liked a certain guide. In the past, Guide ID field was of a Reference type and not a Multi-Reference type. When Guide ID was of a Reference type, this query worked fine:

wixData.query('Likes')
    .eq('guideId', guide._id)
    .eq('memberId', memberId)
    .find();

I needed to convert the Guide ID field into multi-reference field and now the query doesn’t return results.

Does anyone know how to rewrite the query above to find a given Guide ID and a given Member ID with Guide ID being of a Multi-Reference type?

To include a referenced field in the query, you’ll need to use include.

These docs explain it a little better than I would :sweat_smile: - include - Velo API Reference - Wix.com

hi Mikhail

You can refer to this Wix Velo documentation:

Hi @noahlovell and @valentin_wackermedia!

I came across that documentation as well as documentation on queryReferenced() function. queryReferenced() is what I ended up using.

The documentations are written well but I couldn’t figure out exactly what supposed to go into item parameter of queryReferenced(). Now that I understand it, the parameter is clear but when I didn’t know what the “referring item’s ID” is supposed to be, I couldn’t get the function to work.

In any case, if anyone else is struggling with the same thing, here’s the solution of how to query a collection with a multi-referenced field to find if a specific item is referenced in a multi-reference field:

01. Find ID of item/document in Likes collection
Start by creating a function that will lookup the item ID representing member’s record that shows all of the items that the member liked. For added clarity, it’s not the member’s ID that is needed, it’s the ID of item that represents member’s record in Likes collection that is being looked up by this function:

async function findLikesItemId(memberId) {
    // initiate variable to hold item ID from Likes collection
    let likesItemId;
    // check if member liked any guides
    await wixData.query('Likes')
        .eq('memberId', memberId)
        .find()
        .then(queryResult => {
            // if member liked guides, return member's like item ID for liked guides
            if (queryResult.items.length > 0) {
                likesItemId = queryResult.items[0]._id;
            }
        });
    return likesItemId;
}

02. Store Item ID from Likes Collection
Next, you’ll need to pass the ID of member that you’re interested in to the findLikesItemId function and store its result in another variable that can be used by the second function below:

const likesItemId = await findLikesItemId(memberId);

03. Query Likes Collection To Find If Member Liked Specific Guide
Lastly, you’d need to use the likesItemId variable value as well as ID of a guide/blog/article/comment or whatever you’re working with to look up and see out of all items that user liked if that user liked a specific one. That is done using this function:

async function checkIfGuideIsLikedByMember(likesItemId, guideItemId) {
    // initiate variable to hold the answer
    let isGuideLikedByMember;

    // if item ID from Likes collection for the member is not available, then member hasn't liked any guides yet
    if (!likesItemId) {
        isGuideLikedByMember = false
    } else {
        // if item ID from Likes collection for the member is available, look up all of the guides member liked
        await wixData.queryReferenced('Likes', likesItemId, 'guideId')
            .then(likedGuides => {
                // if member liked guides, check if member liked this guide
                if (likedGuides.items.length > 0) {
                    let foundGuide = likedGuides.items.find(likedGuide => likedGuide._id === guideItemId);
                    // if member didn't like this guide, record that
                    if (!foundGuide) {
                        isGuideLikedByMember = false;
                    } else {
                        // if member liked this guide, record that
                        isGuideLikedByMember = true;
                    }
                } else {
                    // if member unliked all of the guides, record that.
                    isGuideLikedByMember = false;
                }
            });
    }

    return isGuideLikedByMember;
}

I was hoping that there’s a much simpler solution, something along the lines of how query() function works, but it doesn’t seem like there is. Good news is that there is a solutions, albeit a convoluted one. Code above does get the job done.

If anyone finds a simpler solution, I’d love to know about it!

1 Like