How to Query 2 Tables and filter them out?

Hi! I’m trying to check 2 data points.

I have managed to get the NFT owned by a specific user on the Cloud function, but I want to query them again and see if the NFT is currently for sale in the Marketplace Contract address.

I’ve been following the Rarible Clone Tutorial, and I have used NFTAdded table to see if the TokenId exist.

However, I’m not sure how to Query them in just one Query or two. Because what I did for now is, I queried all the NFTOwned by a specific user, and then I also queried all the NFTAdded and tried to use 2 for loops to compare each data and put them in the finalResult and thrown it to the frontend. However, I think this is quite a heavy task for the server. So I’m trying to figure out on how to query them without comparing 2 datas in loops.

Hi @appsofdave

Could you share the code exmaples you already used?

1 Like
Moralis.Cloud.define("getAllUserNFT", async (request) => {
  
  const query = new Moralis.Query("NftAdded");
  query.notEqualTo("isSold", true);
  query.select("uid","askingPrice","biddingTime", "tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.username");

  const queryResults = await query.find({useMasterKey:true});
  const nftForSaleResult = [];
  for (let i = 0; i < queryResults.length; ++i) {

    if (!queryResults[i].attributes.token || !queryResults[i].attributes.user) continue;

    nftForSaleResult.push({
      "uid": queryResults[i].attributes.uid,
      "tokenId": queryResults[i].attributes.tokenId,
      "tokenAddress": queryResults[i].attributes.tokenAddress,
      "askingPrice": queryResults[i].attributes.askingPrice,
      "biddingTime": queryResults[i].attributes.biddingTime,
      "createdAt": queryResults[i].attributes.createdAt,

      "symbol": queryResults[i].attributes.token.attributes.symbol,
      "tokenUri": queryResults[i].attributes.token.attributes.token_uri,
      "ownerOf": queryResults[i].attributes.token.attributes.owner_of,
      "tokenObjectId": queryResults[i].attributes.token.id,
      
      "sellerUsername": queryResults[i].attributes.user.attributes.username,
    });
  }


  const query2 = new Moralis.Query("EthNFTOwners");
  query2.equalTo("contract_type", "ERC721");
  if(request.user.get("accounts")){
      query2.containedIn("owner_of", request.user.get("accounts"));
      const queryResults2 = await query2.find();
      let results = [];
      for(let i = 0; i < queryResults2.length; ++i){
          results.push({
              
              "uid": '',
              "tokenId": queryResults2[i].attributes.tokenId,
              "tokenAddress": queryResults2[i].attributes.tokenAddress,
              "askingPrice": '',
              "biddingTime": '',
              "createdAt": '',
      
              "symbol": queryResults2[i].attributes.symbol,
              "tokenUri": queryResults2[i].attributes.token_uri,
              "ownerOf": '',
              "tokenObjectId": queryResults2[i].attributes.id,
              
              "sellerUsername": '',
          });
      }
      
      const finalResult = [];

      for(let i = 0; i < results.length; ++i){        
          for(let j = 0; j < nftForSaleResult.length; ++j){
              if(results[i].tokenId === nftForSaleResult[j].tokenId) {
                finalResult[i] = nftForSaleResult[j];  
              } else finalResult[i] = results[i];
          }
      }  
        return finalResult;
  }
  return;
});

you could keep a hash map with key being tokenId and value nftForSaleResult[i], and then instead of doing the second for you could only query the hash map like your_hashmap.get(tokenId)

like

      for(let i = 0; i < results.length; ++i){
          result2 = your_hashmap.get(results[i].tokenId)

Thanks for the idea, however, what I’m trying to achieve is to query them both and compare them before we push data on the results.