Sign In Register

How can we help you today?

Start a new topic
Answered

Possible to store only parts of NoSQL request?

Hi, i've noticed that when i run a request on a NOSQL item, it overwrites the entire NOSQL item with the request data.


Is it possible to just update a specific item value, instead of an entire NOSQL item?


Example


NOSQL item


playerStash{

value1 "3"

value2 "five hundred-6"

value3 "moredata"

}


Best Answer

Hi Laura,


Sorry about that. The original error was coming from my attempt to concatenate the field name "playerStash."+data.slot. To resolve this, you'd need to construct the object you're using to update the document prior to performing the query, so it would look something like this:

 

var data = Spark.getData().ITEM2;

var updateObj = {};

updateObj["playerCharacter2Items.InventorySlot"+data.slot] = data.item;

 

Spark.runtimeCollection("PlayerData").update(

{"playerId":Spark.getPlayer().getPlayerId()},

{$set:updateObj}

);


Give this a go and let us know how you get on.


Regards,

Vinnie


Hi Laura,


You can use Mongo's $set operator to update individual fields within a document. For example:


Spark.runtimeCollection("myCollection").update({"playerId":Spark.getPlayer().getPlayerId},{$set:{"value1":10}})


If you have any further questions please let us know.


Regards,

Vinnie

I currently use something like this to update data.


With your above example, should i just use that 1 liner, or maybe can you post an example based on my existing code? Thank you.


var playerDataList = Spark.runtimeCollection("PlayerData"); // this will get the collection of player data

    var ID = Spark.getPlayer().getPlayerId(); // first we get the id of the current player

    var playerBaseData = Spark.getData().STASH2; 

    var currentPlayer = {

        "playerID": ID,

        "playerStash2": playerBaseData

    }; // we construct a new player from the data we are about to input into the player data

    playerDataList.update({

        "playerID": ID

    }, //Looks for a doc with the id of the current player

    {

        "$set": currentPlayer

    }, // Uses the $set mongo modifier to set old player data to the current player data

    true, // Create the document if it does not exist (upsert)

    false // This query will only affect a single object (multi)

    );

Hi Laura,


Using the $set operator means there should no longer be any need to first retrieve the existing player document and modify it before updating your collection. Something like this should do the trick:


Spark.runtimeCollection("PlayerData").update(

    {"playerID":Spark.getPlayer().getPlayerId()},

    {"$set":{"playerStash2":Spark.getData().STASH2}} //you can update multiple fields using {$set:{"playerStash1":myValue1, "playerStash2":myValue2,...etc}}

)


Give this a go and let us know how it works for you.


Regards,

Vinnie


1 person likes this

Hi Vinnie, this works to store a specific value, but the problem is the Create Log Event Attributes, and created GS Data within Unreal, overwrites all the other values inside that NOSQL item (in above example playerStash2).


Attached is an image of my Unreal node setup (switching between different player stashes), and the NOSQL item i try to update. When i run above code only one value remains inside the NOSQL table. I can circumvent this when i save all values at once, but i want to preserve bandwith, hence my question. 


image


Hi Laura,


I see. In this situation, it will depend on what data you're sending to your event (your playerBaseData value). For example, if you're sending a single inventory item and you know which slot you wish to store it in you could use:


Spark.runtimeCollection("PlayerData").update(

    {"playerID":Spark.getPlayer().getPlayerId()},

    {"$set":{"playerStash2.StashSlot10":Spark.getData().STASH2}}

)


If, on the other hand, you were sending an object with multiple items to store, and which slots to store them against, you would need to include the path to said item slots, e.g.


playerBaseData: {"playerStash.StashSlot1":"item1","playerStash.StashSlot2":"item2","playerStash.StashSlot5":"item3"}


then you could update the fields required using:


Spark.runtimeCollection("PlayerData").update(

    {"playerID":Spark.getPlayer().getPlayerId()},

    {"$set":playerBaseData}

)


Alternatively, if you don't know in which slot you wish to store your items, you would need to first retrieve the existing document, iterate through it to find an empty slot, update that slot's value with that passed in, the update the database document with the new data.


I hope this helps. If you have any further questions please let us know.


Regards,

Vinnie

Thanks for the examples. 

Is there a way to use a single script to save values in the root, with changing item slots?

Hi Laura,


Sorry, just to clarify, when you metioned changing item slots - you want the value being sent to be stored in the first available item slot, or one specified in the data?


Regards,

Vinnie

The one specified. 

Hi Laura,


Let's say the data in 'Spark.getData().STASH2' resolves to this:


{"item":"Sword-Knight-0","slot":"StashSlot5"}


You could apply this to the player's document using:


var data = Spark.getData().STASH2;


Spark.runtimeCollection("PlayerData").update(

{"playerId":Spark.getPlayer().getPlayerId()},

{"$set":{"playerStash."+data.slot:data.item}}

);


If you only specifiy the slot number in the data being sent:


{"item":"Sword-Knight-0","slot":5}


you would need to change the query to:


Spark.runtimeCollection("PlayerData").update(

{"playerId":Spark.getPlayer().getPlayerId()},

{"$set":{"playerStash.StashSlot"+data.slot:data.item}}

);


Does that make sense? If you have any further questions let us know.


Regards,

Vinnie

I try to use the last code snippet in my cloud code query, but i get this error


missing : after property id

Hi Laura


It looks like a small typo in the code can you change  the + to : in this line 

{"$set":{"playerStash."+data.slot:data.item}} to 

{"$set":{"playerStash.":data.slot:data.item}}


Regards

Katie

Could you post the entire Cloud Code again, when i use this example



var data = Spark.getData().ITEM2;

Spark.runtimeCollection("PlayerData").update(

{"playerId":Spark.getPlayer().getPlayerId()},

{"$set":{"playerCharacter2Items.InventorySlot":data.slot:data.item}}

);


I get now this error missing } after property list (event/Save_Player2_Item.js#10)


Thank you

Answer

Hi Laura,


Sorry about that. The original error was coming from my attempt to concatenate the field name "playerStash."+data.slot. To resolve this, you'd need to construct the object you're using to update the document prior to performing the query, so it would look something like this:

 

var data = Spark.getData().ITEM2;

var updateObj = {};

updateObj["playerCharacter2Items.InventorySlot"+data.slot] = data.item;

 

Spark.runtimeCollection("PlayerData").update(

{"playerId":Spark.getPlayer().getPlayerId()},

{$set:updateObj}

);


Give this a go and let us know how you get on.


Regards,

Vinnie


1 person likes this

Thank you Vinnie, this seems to work now, great.


Btw, do you have an example for loading data via an array for Unreal?


We tried this but doesn't work. Ps. let me know and i create a new topic for that question.


image


Login to post a comment