I want to mark node as deleted (and not actually delete the node) and i'm not sure if to set a property in the node(deleted:0/1) or set label to the deleted node. which way is more efficient and right?
From my point of view it's label, because they are indexed by default.
This article could help you - http://graphaware.com/neo4j/2015/01/16/neo4j-graph-model-design-labels-versus-indexed-properties.html
It depends entirely on your use case. In many cases you will actually delete the node. For others you can set a property or add a label. From a performance point of view there shouldn't be much of a difference.
The most important thing is to understand how your application is going to interact with the node that is marked deleted. Do you still want it searchable? How are people searching now and if you don't want it searchable what is the easiest way for you to modify your query to exclude deleted information? Will you ever need to restore the node or query it at a later time?
Related
I got a problem when designing a graph model with million users. I need to store information that user is registered or non-register.
As I see we have 2 options:
Store a property "register = true/false" in each user node. So with 1 million user, we have 1 million properties "register".
Store a Registered node then make relationship just for registered user to this node. So we have number of relationship equal exactly with the registered user.
Which option is better in performance searching also about minimum storage?
Thanks in advance,
Modeling your data as a graph is a difficult thing to pin down exactly. Typically, when it comes to NoSQL databases, the most important thing to consider is how you will be using your data, and to model it based on that.
Using the external node might run into performance problems, as Neo4J typically starts to run into issues during traversing as it approaches around 10,000 relationships in a single node. You will be well above that limit with an external "Registered" node; on the other hand as long as you are not anchoring your search to that node, it should be okay.
No matter which route you go, the query you described in the comments will likely anchor on (start with) the user, then traverse to who their friends are, and then for each friend, it will check whether it
A. has the "registered" property set to 'true'
B. has a relationship to the "Registered" node.
Each of these methods appears to have a similar execution time, and indexing on the "registered" property will have negligible impact because it is not being used as an anchor (presumably; you would have to PROFILE your query with both methods to find out for sure). So, like you mentioned, one might consider the space restraints.
Besides that, there is not much difference from a performance analysis perspective between the two methods that I can see.
A third option, mentioned by #InverseFalcon, is to use an additional label, ':Registered' on those nodes that are registered. This might well result in a faster comparison time than keeping it in a property, as labels will be inlined in the node store and can be checked there, whereas properties might have an additional level of indirection to the property store.
So I've just worked through the tutorial and I'm unclear about a few things. The main one, however, is how do you decide when something is a relationship and when it should be a Node?
For example, in the Movies Database,there is a relationship showing who acted in which film. A property of that relationship is the Role. BUT, what if it's a series of films? The role may well be constant between films (say, Jack Ryan in The Hunt for Red October, Patriot Games etc.)
We may also want to have some kind of Character bio, which would obviously remain constant between movies. Worse, the actor may change from one movie to another (Alec Baldwin then Harrison Ford.) There are many others like this (James Bond, for example).
Even if the actor doesn't change (Main roles in Harry Potter) the character is constant. So, at what point would the Role become a node in its own right? When it does, can I have a 3-way relationship (Actor-Role-Movie)? Say I start of with it being a relationship and then, down the line, decide it should've been a node, is there a simple way to go through the database and convert it?
No there is no way to convert your datamodel. When you start your own Database first take time to find a fitting schema. There is no ideal way to create a schema and also there are many different models fitting to the same situation without being totally wrong.
My strategy is to put less information to the relationship itself. I only add properties that directly concern the relationship and store all the other data in the nodes. Also think of properties you could use for traversing the graph. For example you might need some flags or even different labels for relationships even they more or less are the same. The apoc.algo.aStar is only including relationshiptypes you want (you could exclude certain nodes by giving them a special relationshiptype). So keep that in mind that you take a look at procedures that you might use later.
Try to create the schema as simple as possible and find a way to stay consistent in terms of what things are nodes and what deserves a relationship. Dont mix it up.
Choose a design that makes sense for you! (device 1)-[cable]-(device 2) vs (device 1)-[has cable]-(cable)-[has cable]-(device 2) in this case I'd prefer the first because [has cable] wouldn't bring anymore information. Irrespective to what I wrote above I would have a lot of information in this [cable] relationship but it totally makes sense for me because I wouldnt want to search in a device node for cable information.
For your example giving the role a own node is also valid way. For example if you want to espacially query which actors had the same role in common I'll totally go for giving the role a extra node.
Summary:
Think of what you want to do with the data and choose the easiest model.
Having successfully created a spatial index, created a node and added it to my index, I'd now like to be able to delete the node (easy) and remove it from the spatial index (not so easy).
At time of writing, the documentation does not cover this.
Looking at the index i can see what to clear up, but on my simple DB i'm not confident if this is a protocol to follow or just a rule of thumb.
My node (within the index) is two "rtree" relationships away from the root of the layer, which i can clean up, if advised to.
Is there an api to delete my node?
If not, is this a good pattern to tidy up the index once i destroy the node in the graph?
Thanks.
When you delete a node it should be automatically removed from any index to prevent orphaned entries. If you experience a different behaviour, I'd consider this being a bug.
Yes, cleaning the index after a node removal is the right thing to do. a PR would be most welcome! Also, make sure removal is idempotent (I believe it already is).
i am currently working on a project in which i have to implement a notifications system. I am a really starte with graphs dbs, so i dont know which would be the best approach to implement this. I have been thinking in two options:
1-Creating notifications nodes, relating them to the user with a relation type pending or read. When i insert them i insert them like pending and when the user read them, i change the relation type to read.
2-Creating notifications nodes, relate them to the user and add some property to the relation..."status" (pending,read). Then add an index to that property.
I dont if i am well oriented, i would appreciate if you could point me in what direction.
Thanks in advance. Rodrigo
Rodrigo,
it depends a bit on what amount of stuff you are going to expect, and how you are going to ask for this. I think something like
USER---READ--->TODAY---->Status1
|
----UNREAD--->TODAY---->Status2
Would both let you group status for both READ/UNREAD and some property regarding time or otherwise, when a lot of read status are starting to accumulate over time, while still letting you ask traversals over them ...
Would that work?
/peter
I am trying to change the index of a node, because there are some specific nodes that at all times needs to be at the bottom of my tree. I tried to change the Node.Index, but that did not change anything. So my question is: How do I change the Index of a PVirtualNode?
Thanks! - Jeff
To change the index of node A, find the node B that has the index you want A to have, and then call Tree.MoveTo(A, B, amInsertBefore, False). B and everything after it will shift down by one to make room for A, and their Index fields will be recalculated. This works even if A doesn't yet exist in the tree (such as just after calling MakeNewNode).
If you're using Index to associate each node with its corresponding data value in a list or array, then you'll find this largely ineffective for re-ordering the displayed values.
You canot change the index of a node. Normally when using VirtualStringTree you hold your data in your own data structure separate from the tree and access the data from the events.
You can also store data directly in the nodes (using a record), but I prefer the other approach because it keeps the logic out of the tree view.
For example, you could store the data in a list and access this list in the GetText handler (you can use Node.Index). Then, if you want to reorder the items, just reorder your list and everything else will happen automatically (you might have to call Invalidate on the tree).
Pseudocode:
Initializing:
Tree.RootNodeCount := MyList.Count;
In the GetTextevent:
NodeText := MyList [Node.Index];
Reordering:
Reorder (MyList);
Tree.Invalidate;
Given that you are still using the tree view control as a container, the ideal solution offered by Smasher is not available to you.
One rather obvious solution, given that your tree view has no hierarchy (i.e. it's a list) would be to use the Sort method with your own compare function (OnCompareNodes).
The other blindingly obvious strategy would be to add the node that you want at the bottom last. If you need to add other nodes later, then insert them above the special last node with InsertNode. This simple approach will probably suffice for the problem as you have described it.
TVirtualNode is a doubly-linked list, it's not a index-based structure: you change the index of a node by removing it and adding it where you want it.
Look into DeleteNode and AddChild.