Lookup returns every rows extra columns as an array when joining

Cloud function for the join:

// this goes in the Moralis server Cloud Functions section
Moralis.Cloud.define("getUserCampaignsData", function(request) {
    const user = request.user;
    const query = new Moralis.Query("DonatedCampaign");

    const pipeline = [
      // only transfers to or from userAddress
      {match: {donor: user.id}},
      {lookup: {
      from: "Campaign",
      localField: "campaign",
      foreignField: "objectId",
      as: "campInfo"
    	}}
    ];
  
    return query.aggregate(pipeline);
  });

Campaign class https://i.imgur.com/76d8epZ.png
User class: https://i.imgur.com/ARsRnOR.png
Donated Campaign class: https://i.imgur.com/NhGzZ9g.png

Picture of the result in the networking tab https://i.imgur.com/tpigtnX.png

Also somewhere in your documentation it explicitly says that _id is not thing https://i.imgur.com/391RA1o.png

Yet I get _id values?

Also when i change the foreign key to ā€œ_idā€ I get no rows returned in campInfo

you. can also try to see more info on google on how to do it with parse server and mongo db.

for aggregation isnā€™t master key required?

you can add images here directly too, no need to upload them somewhere else

Iā€™m slowly starting to figure it out, donā€™t know why your lookup in my eyes still doesnā€™t work how I expect it to but I realized why I was getting different field names.

When you return the array with the extra data in the as:'name" field in lookup it turns it into just a normal mongoDB kinda deal and it changes all the underlying field names so you get stuff like _id and _p_owner instead of just owner.

I couldnā€™t figure out how to fix the join Iā€™m still getting all those extra rows I would expect the lookup to filter out so I just manually nulled all the invalid rows when rendering.

import { useState, useEffect } from "react";
import { Icon, Card, Button } from 'semantic-ui-react';
const Moralis = require('moralis');
import {useMoralis} from 'react-moralis';




const  CampPage = () => {
    const {user} = useMoralis();
    const [camps, setCamps] = useState(null);


    useEffect(() => {
        async function queryWrap() {
             if(user){
                const DonatedCampaign = Moralis.Object.extend('DonatedCampaign');
                const camps = new Moralis.Query(DonatedCampaign);
                camps.equalTo('donor', user);
                const temp = await Moralis.Cloud.run('getUserCampaignsData');
                
                setCamps(temp);
             }
            }
            queryWrap();
        }, [user]);

    
    if (camps){
        console.log(camps[0]['campInfo'][0]);
        console.log(camps[0]['campInfo'][0]['_p_owner']);
        //console.log(JSON.stringify(camps[0].get('campaign')));
        return (
            <div>
                <h1>Voted Campaigns</h1>
                <p> Your previously voted campaings:</p>
                <div>
                
                    {camps.map(campaign => (
                        
                        campaign['campInfo'].map(possibleCamp => (
                            possibleCamp['_id'] === campaign['campaign']['id'] ? (
                                <Card>
                                    <Card.Content>
                                        <Card.Header>{possibleCamp['name']}</Card.Header>
                                        <Card.Meta>
                                            <span className='date'>{campaign['next_vote'].toString()}</span>
                                        </Card.Meta>
                                    </Card.Content>
                                    <Card.Content extra>
                                        <a>
                                            <Icon name='user' />
                                            {possibleCamp['_p_owner']}
                                        </a>
                                    </Card.Content>
                                </Card>
                            ) : null
                        ))))
                    }
                </div>
            </div>
        )}else{
            return <div> broken </div>;
        }



}



// const getCampaigns = () => {
//     return Moralis.Cloud.run('getUserCampaigns');
// }

// export async function getStaticProps(){
//     const temp = await getCampaigns();
//     console.log(temp);
//     return {
//         props: {
//             campaigns: JSON.parse(JSON.stringify(temp))
//         }
//     }
// }
export default CampPage;

Can you suggest an aggregate function that is doing what ternary mapping is doing in my render?

Also I did add the , {useMasterKey:tree} (correct syntax thought because no error) and it made no difference.

Here is the moralis log for one of those queries

Iā€™m still getting this same thing I noticed that I was comparing a pointer of an object to an objectId so I tried to be a little more explicit noticing the pointer object itself had the objectID stored but I still get the same thing

// this goes in the Moralis server Cloud Functions section
Moralis.Cloud.define("getUserCampaignsData", function(request) {
    const user = request.user;
    const query = new Moralis.Query("DonatedCampaign");

    const pipeline = [
      // Get Campaigns the current user has donated to in the lookuptable
      {match: {donor: user.id}},
      {lookup: {
        //From the DonateDampaign table match the campaign pointer to the Object id in the Campaign table
      from: "Campaign",
      //THIS IS THE LINE I JUST UPDATED campaign is a pointer to a Campaign.
      localField: "campaign.objectId",
      foreignField: "objectId",
        //Call this table campInfo
      as: "campInfo"
    	}
      }
    ];
  
    return query.aggregate(pipeline,{useMasterKey:true});
  });