CosmosDB get number of nested children - azure-cosmosdb

I try to limit the depth on which child objects can be defined on their parent.
Example Child simplified object:
{
"name": "childgroup",
"clientId": "1ea87515-63d2-41b8-b327-5a179394bd4c",
"parentId": "9a6d3b39-3143-492f-b729-417a721640c9",
}
Example Root simplified object
{
"name": "Root",
"clientId": "1ea87515-63d2-41b8-b327-5a179394bd4c",
"parentId": null,
}
So for now the distinction between a Root and a child is that the Root object has no parentId.
I want to limit the user to make a infinite amount of children that depend on the previous parent. So the child from the previous parent is now the parent of a new child object.
Thus i need to check when my users want to make a new object on how "deep" the last child is given the parentId the user provides me.
How could i make this query is cosmosDB semi-efficient?
I could query every parent from the child and count the number for every time it finds a parent, but that seems to inefficient...

Related

NGXS: Can we split out an object from array into a substate?

My top level state model looks like this:
{
listOfItems: [], // Item[]
selections: {
itemId: 0
}
}
The items list may contain 10 different shopping items.
When the user clicks on an item, it updates the selection, and my #Selector will rerun.
Action: Set Item Selection
#Action(Item.Select)
setState(
{ setState }: StateContext<ItemsModel>,
{ itemId }: Item.Select
) {
setState(patch({ selections: patch({ itemId }) }));
}
Selector: Select Current Item
#Selector()
static getSelectedItem(state: ItemModel): Item {
return state.itemList.find(i => i.itemId === state.selections.itemId);
}
Problem is: I have up to 20 actions to perform on the selected Item. This results in:
Lots of .find() lookups to find item in the original array (both selector and actions)
Actions to perform on the listOfItems are in the same place as those to perform on a specific Item
I would like to: Keep the array and selection in this state, but separate out the "selected item" into a new substate, where the child state's model can just be Item type. This way I can encapsulate all the actions on Item in a different place to actions on the Items[] array.
I'm not sure how to keep them in sync. I need to keep the 'selectedItem' state up to date when the selection itemId changes in the parent. I also need to make sure any mutations to the selectedItem are reflected in the original array in the parent.
This seems like it might be more of a fundamental problem with how you are trying to represent your application state. Have you thought of normalizing your list of items? Or at least using a key/value lookup object instead of an array? You wouldn't need to use the .find() to do your lookup and could access the key of the object via the unique id you are interested in. Let me know if that is of any help!

Delete all child data based on parent node id in tree

I am using kentico application where i have to delete all child items which contains either node id of parent or parentnodeid of parent based on the child inside there.
Below is the screen shot:
In this picture we can see we have a parent node called membership and inside one child called Blog. Under of Blog which node id is 583 having 29 child. Now I am running a code and getting all the child data under of that parent as a list.
Below is the screen shot:
Now i have to remove all the child data from list whose parentnodeid or parent-parent node id is 583 (Blog).
Below is the code used to get the list of all parent and child items:
TreeProvider tree = new TreeProvider();
var childNodeDataSet = tree.SelectNodes(childNodeId, null, SiteContext.CurrentSiteName);
var getAllChildItems = childNodeDataSet.Items[0].AllChildren;
var getItems = getAllChildItems.ToList().OrderBy(a=>a.NodeAliasPath);
As we can see above code childNodeId is nothing but the Membership page node id. Using this i am getting all the child items.
Now in this getItems i have all the values where i have to remove Blog page parent and child completely.
I tried this code to remove the matching parent item from list:
string excludeFileName = "583, 683, 686, 687";
string[] arrStringList = excludeFileName.Split(',');
foreach (var excName in arrStringList)
{
getItems.RemoveAll(a => (a.NodeID == Convert.ToInt32(excName.Trim()) || a.NodeParentID == Convert.ToInt32(excName.Trim()))
|| (a.Parent.NodeID == Convert.ToInt32(excName.Trim()) || a.Parent.NodeParentID == Convert.ToInt32(excName.Trim()))
|| (a.Parent.Parent.NodeID == Convert.ToInt32(excName.Trim()) || a.Parent.Parent.NodeParentID == Convert.ToInt32(excName.Trim()))
|| (a.Parent.Parent.Parent.NodeID == Convert.ToInt32(excName.Trim()) || a.Parent.Parent.Parent.NodeParentID == Convert.ToInt32(excName.Trim())));
}
This code is working fine if i know particular node has how many level.
But if some of the node don't have that much level then in that case this code is giving exception.
If found any issues please let me know.
I am a little confused at the path you're taking. If you want to get all children of a particular node, why not just get all nodes where the NodeAliasPath is like "The/Parent/Node/Path"+"/%"?
This will select all the children nodes all the way down.
If you only want to grab a certain number of levels, you can get the Parent's NodeLevel, and then in the query add a NodeLevel <= "+(ParentNodeLevel+2) to grab all the children and grandchildren only.
To exclude certain nodes, you can also put a "NodeID not in (123,234)".
Perhaps if you can clearly say what you are trying to accomplish we can help out easier!
PS: I Put the SQL, but the DocumentQuery object has most of these in methods, like .WhereNotIn("NodeID", ListOfNodeIDsToExclude)

inserting a nested attributes array element in dynamodb table without retrieving the entire item

looking for an answer to this question if possible, not looking for a refactoring advice or redesign, i just need to understand what else I am missing here :
I have an existing item in dynamodb:
{
"CartId": 321,
"UserId": usr555,
"CartItems": [
{
"ProductId":59999,
"Quantity": 1
},
{
"ProductId": 58888,
"Quantity": 2
}
]
}
in my code I want to insert another nested attribute into the array CartItems in the item above. i can't find a way of doing this without retrieving the entire item and then inserting, which could amount to KBs in size.
all I want to do is insert a single array element in an existing nested attribute without having to retrieve the item.
the language I am using is nodejs and the function is DynamoDB.put.
UpdateExpression attribute supports SET action and SET action supports list_append function. Since list_append function operands must be list, enclose the new value within a list as below.
response = dynamodb_client.update_item(TableName='your_table',
Key={'CartId':'321'},
UpdateExpression='SET CartItems = list_append(CartItems, :val1)',
ExpressionAttributeValues = {':val1':[{'ProductId':12345, 'Quantity': 100}]})
Hope this helps

react create dynamic tree recursively

thanks for reading and helping. Here is my situation so far:
I have much data in database, each piece of data has id, parentid(which means you can find the id of its parent using this parentid ), name, description.
I want to create a dynamic tree using react,but I do not know how many levels of nodes I have. Each node represents for an id in database. An user clicks on a node A on this tree, the children nodes whose parentid equals to A's id will show/hide.
I do not intend to retrieve all the data because it will take long time. Now I am able to get one node's children by sending request and get response.body:
getChildren(id){
ajax.get('http://localhost:8080/configmgmt/code/category/retriveTree/' + id)
.end((error, response) => {
if (!error && response) {
console.dir(response.body );
this.setState(subdata:response.body});
} else {
console.log('There was an error fetching from database', error);
}
}
);
}
in render part, I wrote:
{this.state.subdata.map((rb,index)=>{
return <li><div>{rb.name}</label></div></li>})
}
Here comes the question, I still do not know how to create the tree recursively(because any node might has its children nodes ). how to do this when we can only get a node's children nodes from the database?
I would do your task in two steps:
Create a structure for an augmented tree with loading status flags. It should have a structure like this (this is pseudocode):
class Node {
loaded: boolean,
expanded: boolean,
children: list<Node>
}
Create a component for this:
If node isn't expanded don't render its children
If use clicks on expand sign
If children are loaded, do nothing, just change the expanded field
If children aren't loaded
set expanded to true
initiate ajax request
as soon as the request completes, set loaded to true, and assign children
Creating a component which recursively uses itself isn't a problem. If you don't know how to do this read here: how to render child components in react.js recursively

meaning of "Size of one child value" limit 10Mb for firebase

The firebase documentation specifies the limit for "Size of one child value" is 10Mb.
Does that mean the size of the JSON object of that child?
For example, using example in the documentation:
{
"users": {
"mchen": {
"friends": { "brinchen": true },
"name": "Mary Chen",
// our child node appears in the existing JSON tree
"widgets": { "one": true, "three": true }
},
"brinchen": { ... },
"hmadi": { ... }
}
}
Is node "users" considered as a child here? if so, does it mean if the # of users gets large(like hundreds of thousands, assuming each user has 100 bytes data), then the sum of sizes of all users will be exceeding the 10Mb limit? Thanks
As the documentation says the value of a single node can be at most 10MB. The child nodes under a location are not considered a value, they're just... child nodes.
A tree can be larger than 10MB. Logically thinking this also makes sense: otherwise the entire database could never be larger than 10MB, which is not true.

Resources