Alias field in Realm function

Hello,

I am trying to alias the _id field in a Realm function using the find() method.
According to the documentation, the second parameter in the find() method is a projection.

I have a collection called students with the following fields
_id, firstName, lastName, accountId

I am attempting to alias the return using a projection
Here is a code snippet:

const query = { };
const projection = { _id_:1, studentId: "$_id", };
await students.find(query, projection).toArray()

Here are my results

[
{"_id":“5e8fc09770f5e3f18c730a21”},{"_id":“5e8fc40470f5e3f18c730a22”},{"_id":“5e90838738eff556f0fa48d0”},{"_id":“5e9086a138eff556f0fa48d1”},{"_id":“5e908dba38eff556f0fa48d2”},{"_id":“5eea898c1a3f23cd2980e699”}]

The alias did not work and I am also missing the other fields.

Anyone have an idea? I went through the Realm docs and the samples are very scarce

Hi Herb -

Can you try putting quotes around “_id” and “studentId”? Also, to return any other field you will have to add it to your projection.

For example, I tried something similar and got this snippet to work:

exports = function(arg){

const mongodb = context.services.get("mongodb-atlas");
const itemsCollection = mongodb.db("db").collection("Cat");

  const query = { "name": "joey"};
  const projection = { "_id": 1, "StudentId": "$_id"};

return itemsCollection.find(query, projection)
  .toArray()
  .then(items => {
    console.log(`Successfully found ${items.length} documents.`)
    items.forEach(console.log)
    return items
  })
  .catch(err => console.error(`Failed to find documents: ${err}`))

};

Hello Sumedha,

I tried putting the quotes around the fields and still can’t get the alias to work
const projection = { “_id”: 1, “studentId”:"$_id", “firstName”:"$firstName",“lastName”:"$lastName", “accountId”:"$accountId"};

Unfortunately, the alias is not working. I also tried aliasing other fields (ex: “first”:"$firstName")
Other alias fields don’t appear at all in the output

To be clear, I am using a Realm ‘3rdPartly’ HTTP Get function, not Compass or the CLI

{
[
{
“_id”: “5e8fc09770f5e3f18c730a21”,
“accountId”: “5e89f69d1c9d440000929b9a”,
“firstName”: “Nancy”,
“lastName”: “Doe”
},
{

        "_id": "5e8fc40470f5e3f18c730a22",
        "accountId": "5e89f69d1c9d440000929b9a",
        "firstName": "Pat",
        "lastName": "Doe"
    },
    {
        "_id": "5e90838738eff556f0fa48d0",
        "accountId": "5e89f69d1c9d440000929b9a",
        "firstName": "Michael",
        "lastName": "Doe"
    },
    {
        "_id": "5e9086a138eff556f0fa48d1",
        "accountId": "5e89f69d1c9d440000929b9a",
        "firstName": "Sam",
        "lastName": "Doe"
    },
    {

        "_id": "5e908dba38eff556f0fa48d2",
        "accountId": "5e89f69d1c9d440000929b9a",
        "firstName": "Maria",
        "lastName": "Doe"
    },
    {

        "_id": "5f18c5e9c0764f3b76890023",
        "accountId": "5e89f69d1c9d440000929b9a",
        "firstName": "John",
        "lastName": "Doe"
    }
]

How are you testing your function? Is it with the Realm UI Console?

Do you mind pasting your entire function snippet here as well.

Sure. Its a webhook in Realm.
I’m not actually using a Realm “Function” but a Realm 3rdParty HTTP webhook.

Here is the code:

/*

  • getStudents webhook function request handler.
  • Get a list of students for the given arguments
  • arguments: accountId
  • console execution ex: exports({query: {accountId:‘5e89f69d1c9d440000929b9a’ }}, new HTTPResponse())
    */

exports = async function getStudents(payload, response) {
const {accountId } = payload.query;
const db = context.services.get(“mongodb-atlas”).db(“usersDB”);
const students = db.collection(“students”);
console.log(getStudents accountId:${accountId});

const query = { accountId:accountId };
//const projection = { "studentId": "$_id", };
const projection = { "_id": 1, "studentId":"$_id", "firstName":"$firstName","lastName":"$lastName",  "accountId":"$accountId"};

console.log ('getting students query:', JSON.stringify(query));

response.setHeader("Content-Type","application/json");

//await students.find(query).toArray()
await students.find(query, projection).toArray()
.then(result => {
    if(result) {
      response.setStatusCode(200);
      //response.setBody(`{"students":${result}`);
      response.setBody(`{"students":${JSON.stringify(result)}}`);
    }
    else {
      console.log("students not found:",JSON.stringify(result));
      response.setStatusCode(404);
      response.setBody(`{message:"No students not found for given criteria"}`);
    }
}).catch(err => {
  console.log("error getting students:",err);
  response.setStatusCode(500);
  response.setBody(`{error:${err}}`);
})

}

Hey Herb,

I’m looking into why renaming aliases seems to work sometimes on Realm (e.g. my function), but not in your case

In the meantime @wan has an alternative solution using a pipeline that should give you the same result.

Hi @Herb_Ramos,

If you’re looking to project a field under a different name, and also include other fields as well you should try Realm aggregation pipeline: project document fields. An example for your use case would be:

const pipeline = [
  { "$addFields": {"StudentId": "$_id" } }
  ]

  return students.aggregate(pipeline).toArray()
  .then(students => {
    console.log(`Successfully grouped purchases for ${students.length} customers.`)
    students.forEach(console.log);
    return students
  })
  .catch(err => console.error(`Failed to find documents: ${err}`));*/

Regards,
Wan.

1 Like

Thanks Wan. I will give this a try. I am however curious if there is a bug based on my original request.

Hi @Herb_Ramos,

It is not a bug, and apologies for the confusion.

If your Realm application is linked to MongoDB Atlas version 4.4 (currently available in beta in select regions only), you should be able to project field name alias using find() projection syntax. If you are using the current stable MongoDB Atlas version 4.2, you should use the aggregation pipeline to project field name aliases.

Since your valid code function did not return the projection output aliases, I’m assuming that your MongoDB Atlas cluster is on version 4.2

Regards,
Wan.

3 Likes

Thanks Wan. I will mark this as a solution. I am on 4.2. I have not tried the projection on 4.4 and I am assuming it will work. For now I will used the pipeline aggregate you suggested on 4.2. Thanks again.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.