I use an aggregation to resolve parse pointer referencing the user class. Just wanted to share the solution, since I could not find a solution to this in the docs.
Setup: Product class referencing a Parse.User
// Product uses a pointer to User
// user must be a Parse.User
await new Product().set("description", "foo 9000").set("createdBy", user).save();
Resolve pointer in aggregation
Goal is to create list of all products with the Users referenced by field “createdBy” resolved.
// pipeline to list all products with their users
const pipeline = [
{
// A parse pointer looks like this in MongoDB:
// _p_createdBy:"_User$iGy2IHfsRf3"
// extract the user objectId from the pointer, store it as a new field
// I rely on the fact, that the prefix "_User$" is constant
addFields: {
userId: { $substrBytes: ["$_p_createdBy", 6, 100] },
},
},
{
lookup: {
from: "_User", // name of the Parse.User class within MongoDB
localField: "userId", // the user id we just extracted from the pointer
foreignField: "_id", // the user id in the _User collection
as: "UserLookup", // the array to store the lookup
},
},
{
addFields: {
user: { $arrayElemAt: ["$UserLookup", 0] }, // pick the first element from the lookup
},
},
];
const query = new Parse.Query("Product");
return await query.aggregate(pipeline);
Alternatives
- do not use aggregations for basic listing, just load the Product class use a standard Parse.Query and use “.include” to load the User at the same time.